[moneydance] ProfitCalc extension build 3 and more

Edward Reid edward at paleo.org
Mon May 1 16:07:25 EDT 2006


At 10:54 05/01/06 -0600, Jeff Poole wrote:
>The formatting problem is due to the fact that computers store numbers in
>binary, and there is no exact representation for 0.568 in binary (at
>least, not in the 54 bits you get to represent it for a double precision
>floating point number).

The problem is not with binary, but with using binary FLOATING POINT. 
Floating point is inappropriate for storing monetary amounts (or any 
numbers with exact decimal fractions), since 1/5 cannot be exactly 
represented in binary floating point.

The correct way of storing monetary amounts is to use an integer (pick a 
type that's large enough for the amounts in question) and to save the scale 
factor separately.

For example, in the case given -- a number 36.568 -- the program should 
store the integer 36568 and the knowledge that it is scaled by 1000. This 
number would fit -- barely -- in an unsigned 16-bit integer; a 32-bit 
integer might be appropriate. Even 31 bits (leave a bit for the sign) will 
only store numbers up to about +/- $20 million (2 billion cents), which 
would be adequate for my personal finances (oh how I wish ...) but not for 
a business of any size. So a 64-bit integer is more generally appropriate.

In general, one might have to manipulate the scale factor dynamically. In 
practice, it's usually possible to just build it into the code as 
assumptions, or to store it as a constant. However, a program designed to 
work with many different currencies might have to use more dynamic 
manipulation. For example, for US dollars and cents the scale factor is 
100, but for Japanese yen it is 1. I don't know if any common currencies 
use any other scale factors today.

Even more generally, this is a special case of how rational numbers have to 
be stored for correct results.

I don't know how MD stores its amounts internally, but using integers and 
scale factors is the correct way.

You'll sometimes hear it said that you should store dollars and cents as a 
decimal number, but this misses the point -- it mostly describes the way in 
which a COBOL program describes the variable, and you'll mostly hear it 
from COBOL programmers. Few computers have implemented true decimal 
arithmetic in hardware (aka microcode). Two that did were the IBM 1401 and 
the IBM 360 and its modern descendents. However, neither of these handled 
decimal fractions in the hardware, and even on these systems COBOL 
compilers had to generate the appropriate scale factor code for variables 
with decimal fraction parts. It really is too bad that no well known 
programming languages other than COBOL and PL/I include scaled fixed point 
numbers as part of the language -- it makes working with monetary amounts 
much easier for programmers.

Edward
Art works by Melynda Reid: http://paleo.org



More information about the moneydance-info mailing list