Fun with roundoff error

Bill Gribble grib@gnumatic.com
Tue, 5 Dec 2000 15:08:53 -0600


On Tue, Dec 05, 2000 at 03:33:47PM -0500, Randolph Fritz wrote:
> It's 1.4 series--it is excellent to know that you have fixed this
> class of problems.  May I ask for some details of the exact arithmetic
> system chosen?

There's a document in the gnucash source tree, but Dave moved it last
week and I can't find it :(

The basic idea is that numbers are represented as
numerator-denominator pairs, where the denominator is determined by
the financial context.  The C data type is called 'gnc_numeric', and
there's an API for creating them, converting to and from floating
point formats, and performing arithmetic operations on them.

Each value has a denominator, and each account specifies the
denominator in which it represents its credit/debit amounts.  If a
financial institution represents your balance to the nearest USD
1/100, any additions or subtractions to that account must be in USD
1/100.

Where the "natural" result of a computation can't be represented
exactly in the known denominator of the result (for example,
purchasing 1 share at USD 9 7/8 but withdrawing the money from a bank
account denominated in USD 1/100...  1/1 * 79/8 == USD 9.88) a
rounding/truncation policy must be used, and there are several to
choose from in the API.  There's also an alternate API to exactly
"accumulate" the penny-fractions that can get lost in rounding, but
gnucash doesn't use it at this time.

I would call them "rational" numbers (and some people have) but
gnc_numeric arithmetic operations don't have the traditional rational
number semantics (reduction to relatively prime fraction, etc).

b.g.