
(I know that "Currency" received 0 votes at the OOPSALA conference but maybe someone is interested anyway) I have implemented a type for handling decimal math and a type specialized for monetary values. decimal64 type ------------- The type stores a decimal value with specified numberof decimals exactly and also performs all arithmetic operations (+,-,*,/) using decimal math. (Internally the type stores the value as an int64 value which gives 18 DECIMAL digits precision. Multiply and divide uses a 128 bit temporay to avoid rounding errors) - All std rounding modes are available plus a few extra such as round_to_even. - Construction of a decimal64 can be made from int, double, string literal (e.g. "1.234") and other decimal64 values. - Operations can be made on decimal64 objects with different number of decimals and/or different rounding policy. Result of a binary operation on two decimal64 values will have the number of decimals and rounding policy of the left operand. - Streaming works the same way as floating point values but the scientific format is ignored. There are 2 decimal64 types defined: - decimal64 - all constructors requires specification of number of decimals and optionally rounding mode. decimal64(3.1415, 4, round_to_nearest); - decimal64_spec - a template version of decimal64 where number of decimals and rounding mode are specified as template parameters which allows a default constructor. typedef decimal64_spec<3, round_to_even> decimal3; decimal3 x(3.14), y; The decimal value can be converted into another at any time if a calculation needs to be performed at a higher precision or with another rounding policy. decimal64 x(1.2, 1, round_to_nearest); // calculate x*PI/2 using 5 decimals // result is stored in x with 1 decimal, // rounded with round_to_nearest policy x = x.as_decimal(5) * decimal64(3.14159, 5) / 2; Some things I would specificly like to have comments on: 1. Operations are not allowed on doubles. Double values always need to be converted into a decimal value first. e.g. x * decimal64(3.14, 2). Is this something that is needed? 2. No overflow detection or +inf etc. Just like with the integer types there is no checking for overflow on operations. Money type ----------- The money type uses a decimal type to store a monetary value. The functionality is the same as for the decimal64 type with the following exception: 1. Operations are more limited to detect errors. The limitations are: - Money * Money is not allowed. (Money * Decimal is allowed) - Money / Money is allowed but the result is a Decimal (not money) - Money + Decimal is not allowed (Money + Money is allowed). (The same applies to - and all comparison operators) Integers works as both money and decimal so Money*2 and Money+1 is always allowed. 2. Streaming uses locale moneypunct for formatting and parsing. As with the decimal type two money classes are defined - money_base - construction always requires number of decimals and optionally rounding policy typedef money_base<decimal64> money64; money64 x(100,2,round_toward_infinity); - money_spec - number of decimals and rounding policy are template parameters. typedef money_spec<decimal64, 4, round_toward_neg_infinity> money4; money4 x("9.99"), y; locale library -------------- Some time ago implemented helper classes for locale but I never got around submitting it to boost. I needed it for testing the decimal64/money streaming so I cleaned it up and it is included in the package. Building -------- A jam file for building decimal library is included. I have compiled all files and testcases with VS2002 (VC70) and "g++ (GCC) 3.4.2 (mingw-special)". Couldn't get the boost test jam file to work but command line g++ works fine. g++ libs/decimal/test/decimal64_test.cpp libs/decimal/src/decimal64.cpp g++ libs/decimal/test/money_test.cpp libs/decimal/src/decimal64.cpp libs/decimal/src/money.cpp g++ libs/locale/test/locale_test.cpp libs/decimal/src/decimal64.cpp libs/decimal/src/money.cpp There are some differences in streaming which causes a few test errors for money: - VC70 only inserts spaces in the money format if the "internal" adjustment flag and width is set. g++ always inserts 1 space when specifed in the format. I assumed g++ was right so VC70 fails this test. - The default locale with g++ seem to miss a '-' sign for the money format so it fails tests with negative numbers. Library is available here http://web.telia.com/~u84606172/Boost/ Documentation is available in the download as well.