Decimal Classes
The built-in floating point types, float and double, use base 2 to represent numbers. However, many non-integer decimal numbers (for example, 0.1 and 19.7) cannot be exactly represented in base 2. For some applications, such as accounting and financial computations, the round-off error built into the built-in floating point types is unacceptable.
RWDecimal<T> provides exact representation and computation with decimal numbers. Using RWDecimal<T> objects is the same as using the built-in floating point types; the only difference is that, since RWDecimal<T> uses base 10, there is no round-off error when you work with decimal fractions.
RWDecimal<T> is templatized. This allows you to substitute one of the provided integer classes for <T>.
In addition to
RWDecimal<T>, the Currency Module library provides a templatized fixed decimal class,
RWFixedDecimal<T>, which maintains a fixed number of decimal places during mathematical operations. For the regular
RWDecimal<T> classes, the number of digits after the decimal varies as operations are performed. With
RWFixedDecimal<T> classes, the number of decimal places is fixed either at construction or when the first value is assigned. This approach is useful in situations where the result must always represent an exact number of decimal places, as for example, in a bank account where there must always be exactly two decimal places.
RWDecimal<T> exactly represents decimal numbers that can be written using a sign, N decimal digits, and a decimal point. RWDecimal<T> objects can also take on a few non-numeric values, namely, null, missing, and NaN (not a number). A null value can be used to represent a null entry from a database. A value of missing is useful for indicating a missing value in data which is to be subjected to statistical analysis. A NaN value can result, for example, from division by 0. The exact meaning and treatment of these values is described in Section 6.5, “Special Values.”
Arithmetic using
RWDecimal<T> objects is completely intuitive; addition, subtraction, and multiplication each calculate an exact representation of the result. Because division can produce results that cannot be exactly represented (for example 1/3 = .3333...) the result is approximated to the precision available. For the three exact arithmetic operators, if the result cannot be represented exactly but can be represented with a loss of precision, an inexact value is returned and an error handler is called. An error handler is also called in cases where the result cannot be represented at all due to overflow or underflow. An overflow condition occurs when, through calculation or initialization, when
x > RWDecimal<T>::maxValue() or
x < RWDecimal<T>::minValue(). See the reference section for more information on the
minValue() and
maxValue() functions.