Re: Currency Rounding Errors
- From: Joseph M. Newcomer <newcomer@xxxxxxxxxxxx>
- Date: Sat, 18 Apr 2009 16:38:57 -0400
BCD offers no significant advantages over fixed-point binary. The only reason BCD is
"important" is for bacwkard compatibility to databases created in the 1960s that encoded
in BCD, and the fact that COBOL made BCD usage easy so the mistakes of the past could be
propagated indefinitely into the future. BCD was the "natural" representation of numbers
in the IBM 1620, 1400-series, and their various direct competitors; that is, the
representation of 1234 was, in fact, the characters "1234". These were encoded as
8421F encodings as
0000010 0000100 0000110 0001000
-1234 was
0000010 0000100 0001100 0001001
that is, 4 with a minus-bit set (on the 1620, it was CF8421 coding where C was the parity
(Check) bit and was ignored in representations, F was the flag bit indicating sign, 8421
were the bit values. In the 1400 series, it was CBA8421M, Check, the B bit (minus sign),
A bit (plus sign), 8421, and word mark. On the Honeywell 200 series, it was CBA8421RM
where R was the "record mark".
In the 1400 series, BA8421M meant that -1234 had the B (negative) bit set, so the
represnetation of -1234 was
0000011 0000100 0000110 1001000 "123M"
Note that 1234 was also representable as
BA8421M
00000011 00000100 00000110 0101000 "123U"
00000011 00000100 00000110 1101000 "123D"
The word mark on the high-order byte indicated the end of the field.
Since the data was "naturally" BCD, IBM had to support BCD in the /360 series, or they
couldn't use existing data sets, which would have been a marketing disaster.
But just remember when you see BCD, you are seeing an artifact of the 1960s.
Use fixed-point binary. It does everything you need and is easier to code.
[Note that programmed the IBM 1620, 1400, and Honeywell-200 series, handled transitions of
applications to the /360 series, and generally had to deal with all of these problems in
the mid-1960s. They haven't changed in the slightest]
joe
On Sat, 18 Apr 2009 00:40:23 -0700, "Mihai N." <nmihai_year_2000@xxxxxxxxx> wrote:
Joseph M. Newcomer [MVP]I have a program that works with currency values.
In order to avoid rounding errors, I'm storing my currency values as
64-bit integers.
It all depending on how critical the application is and what kind of
operations you do.
In general there is no way to avoid problems using native datatypes,
(rounding, overflows, etc.) and the only option is to create your
own data type and writing your own operations on that data type.
It relatively easy to do using arrays of bytes, for instance, and
a bit trickier (but faster and smaller) if you go with BCD
(binary-coded decimal).
http://en.wikipedia.org/wiki/Binary-coded_decimal
"decimal fixed-point and floating-point are still important and continue
to be used in financial, commercial, and industrial computing"
email: newcomer@xxxxxxxxxxxx
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
.
- Follow-Ups:
- Re: Currency Rounding Errors
- From: Mihai N.
- Re: Currency Rounding Errors
- References:
- Currency Rounding Errors
- From: Jonathan Wood
- Re: Currency Rounding Errors
- From: Mihai N.
- Currency Rounding Errors
- Prev by Date: Re: C++ vs. C#
- Next by Date: Re: Using SHGetFileInfo causes Assertion
- Previous by thread: Re: Currency Rounding Errors
- Next by thread: Re: Currency Rounding Errors
- Index(es):
Relevant Pages
|