MindlessCode.net: Fixed Point Decimal Class
I recently needed a fixed point decimal support in C++ for an inventory program I'm writing. Normal floating point numbers are not accurate enough to store money or quantities, and so this class was born:
The code is public domain--do what you want to with it.
The class is fairly natural to use. Here's a short example:
#include <iostream> #include "decimal.h" int main(int argc, char *argv[]) { //create decimal with a precision of 2 decimal places and an initial value of 1000.00 decimal bank_accout(2,1000); bank_accout -= decimal(2,25.50); //deduct 25.50 decimal a_check(2,50.78); bank_accout -= a_check; bank_accout += 100; std::cout<<"Accout Balance: "<<bank_accout<<std::endl; return 0; }
Implementation Details
The value of the decimal is stored in an unsigned 64 bit integer. A second variable keeps track of the location of the decimal point (m_precision). For example, 25.75 (with a precision of 4) is stored as 257500.
Since it uses a 64 bit int, you should be able to store a fairly large number with quite a bit of accuracy (264-1). Be careful of overflowing the storage integer--there is no bounds checking. If you cause it to wrap then you will get strange results.
Things You Should Know
When executing the operations +, -, *, /, <, and >, they are executed using the greater precision of the two. Then, after calculation, the precision is changed back to the initial precision of the left-hand side. For example:
decimal dec1(2,25.75), dec2(4, 34.3321); dec1+=dec2; // 60.08, (answer at 4 places is 60.0821)
You can control the rounding method used by the decimal by passing a RoundingMethod (an enum) to the constructor. See the docs below.
Contact
Questions? Comments? Patches? Send them here!
Documentation
The code is pretty well commented (some functions are documented with Doxygen documentation). If you have any questions, just send me an email and I'll try to answer them (see above). Here's a short synopsis:
enum RoundingMethod { Normal, AllUp, AllDown };
Sets the rounding method used.
- Normal: Round 5 and above up.
- AllUp: Round Everything Up
- AllDown: Round Everything Down
decimal(const int precision, const int value = 0, RoundingMethod round = Normal);
Creates a decimal from integer value, with precision decimal points, and round rounding method.decimal(const int precision, const double value = 0.00, RoundingMethod round = Normal);
Creates a decimal from double value, with precision decimal points, and round rounding method.
