[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