architectural issue with gnc-numeric

Derek Atkins warlord@MIT.EDU
Fri Jan 17 19:40:53 CST 2003


I've found an interesting architectural issue with the
gnc-numeric implementation.  In particular, if you are
operating on two numbers of very high (but DIFFFERENT)
precision, you can cause the code to roll-over beyond the
size of the core data types.

As an example, let's say you want to represent some number, like
193.123456789 as 193123456789/1000000000 and want to add
5/10000000000 in order to "round" the number (see gnc-ui-util.c
PrintAmountInternal for an example).  The gnc-numeric code notices
that the denom's are different so it tries to cross-multiply,
computing a new gnc-numeric as a.num*b.denom + b.num*a.denom over
a.denom*b.denom, and then reduces the result.

While that works right on paper, it unfortunately causes a wraparound
in the numerator because we've now tried to create a number greater
than 2^63-1 (MAX_LONGLONG).  In particular, the largest numerator we
can hold is 9223372036854775807, but we're trying to compute
1931234567895000000000, which is obviously greater!  The result is a
"broken" number.  You can see this by changing "print_info.round" to
'1' in app-utils/test/test-print-parse-amount.c and watching it fail.

The obvious fix is to compute the least common multiple of the two
denominators, convert a and b up to the LCM, perform the addition (or
other operation), and then reduce.  If I have time I'll try to make
this change.

However, I'm wondering (for historical reasons) why we chose to
represent numbers as fractions rather than, say, a fixed-point
notation?  In understand the rounding issues with floating point, but
seriously, how often do we really need to represent rational but
"non-repeating decimal" numbers in GnuCash?  I've certainly never been
given 1/3 of a dollar, or 1/3 of a share of stock. ;)

-derek
-- 
       Derek Atkins, SB '93 MIT EE, SM '95 MIT Media Laboratory
       Member, MIT Student Information Processing Board  (SIPB)
       URL: http://web.mit.edu/warlord/    PP-ASEL-IA     N1NWH
       warlord@MIT.EDU                        PGP key available



More information about the gnucash-devel mailing list