Short: I keep getting financial arithmetic results that don't add up
exactly. From time to time my calculations are off by a few
cents but I'm sure there is nothing wrong with my code. What's
the deal?
X-Contributor: David Husnian <76064.1535@compuserve.com>,
Clipper and most computer languages use a binary floating
point format for their real numbers. This causes precision
errors which commonly show up in calculations, comparisons
and when rounding. The problem is related to trying to represent
an infinite number of decimal numbers into a fixed number (and a
small fixed number at that) of binary bits.
Statistically, there aren't any numbers that can be represented
exactly, of course, from a practical standpoint some can be (but
they are all somehow related to powers of 2, like 1/2 or 3/8 or
127/128 or ...).
Taking .275 out to just 16 bits yields:
.0100011000100111 but that is really only .274993896484375. It
is impossible to represent .275 accurately in a binary numbering
system, even with unlimited bits, let alone the 64 bits that
Clipper uses (all of which aren't used for the decimal portion).
Most modern languages use a format defined by the IEEE. An
IEEE-compliant double precision implementation meets the following
criteria:
1. 1 sign bit, 52 bits for the mantissa and 11 for the exponent.
2. 2.22 * 10 -16 is the smallest number that, subtracted from 1.0,
gives something different than 1.0.
3. Normalized to 1023, which means that 10 0 will be kept as 1023,
with 10 -1 as 1022 and 10 1 as 1024.
4. Smallest useable floating value is 2.23 * 10 -308.
5. Largest useable floating value is 1.79 * 10 308.
In the IEEE standard, rounding is considered to be finding the
closest representable number to the "exact" number. Not an easy
task, particularly at the level of Clipper.
There are only two complete solutions: use only integers (for
example, use 1234 to mean 12.34) or use a decimal numeric format
like BCD.
With Visual Objects you will be able to make variable declarations
such as LOCAL i AS INT, which will have the effect of forcing only
integer values into a variable.
Note that when CA-Clipper 5.3 is released, it will have been
compiled and linked with the 8.0 release of Microsoft C, including
the standard math library component.