Decimal data type support, for COBOL-like fixed-point operations on currency/money values.
Author: Piotr Likus
Created: 03/01/2011
Modified: 18/02/2017
Licence: BSD
Version: 1.15
This data type is designed to perform calculation with on-fly roundings & to support correct compare function (floating-point compare is unreliable).
Values are stored internally using 64-bit integer, so maximum number of digits is 18.
Precision is user-defined, so you can use this data type for currency rates.
To store decimal in file you can use "unbiased" functions or use stream i/o.
Example usage:
#include "decimal.h" using namespace dec; using namespace std; // the following declares currency variable with 2 decimal points // initialized with integer value (can be also floating-point) decimal<2> value(143125); // displays: Value #1 is: 143125.00 cout << "Value #1 is: " << value << endl; // declare precise value with digits after decimal point decimal<2> b("0.11"); // perform calculations as with any other numeric type value += b; // displays: Value #2 is: 143125.11 cout << "Value #2 is: " << value << endl; // automatic rounding performed here value /= 1000; // displays: Value #3 is: 143.13 cout << "Value #3 is: " << value << endl; // integer multiplication and division can be used directly in expression // displays: Value: 143.13 * 2 is: 286.26 cout << "Value: " << value << " * 2 is: " << (value * 2) << endl; // to use non-integer constants in expressions you need to use decimal_cast value = value * decimal_cast<2>("3.33") / decimal_cast<2>(333.0); // displays: Value #4 is: 1.43 cout << "Value #4 is: " << value << endl; // to mix decimals with different precision use decimal_cast // it will round result automatically decimal<6> exchangeRate(12.1234); value = decimal_cast<2>(decimal_cast<6>(value) * exchangeRate); // displays: Value #5 is: 17.34 cout << "Value #5 is: " << value << endl;
- def_round_policy: default rounding (arithmetic)
- null_round_policy: round towards zero = truncate
- half_down_round_policy: round half towards negative infinity
- half_up_round_policy: round half towards positive infinity
- half_even_round_policy: bankers' rounding, convergent rounding, statistician's rounding, Dutch rounding, Gaussian rounding
- ceiling_round_policy: round towards positive infinity
- floor_round_policy: round towards negative infinity
- round_down_round_policy: round towards zero = truncate
- round_up_round_policy: round away from zero
In order to use one of these rounding modes you need to declare your decimal variable like this:
dec::decimal<2, half_even_round_policy> a;
and it will perform required rounding autimatically - for example during assignment or arithmetic operations.
For more examples please see \test directory.
Directory structure:
\doc - documentation (licence etc.) \include - headers \test - unit tests, Boost-based
Code documentation can be generated using Doxygen: http://www.doxygen.org/
Tested compilers:
- VS2015 Community
- VS2013 Community Update 4
- Code::Blocks 13.12 + MinGW + gcc 4.8.4
Uses C++11 by default, define DEC_NO_CPP11 symbol if your compiler does not support this standard. To use custom namespace, define DEC_NAMESPACE symbol which should contain your target namespace for decimal type.
For list of project contributors, currently open issues or latest version see project site: https://github.com/vpiotr/decimal_for_cpp