Exact representation of a decimal fraction with a fixed number of digits after the decimal point, with automatic rounding to ensure correct number of decimal places.
More...
|
(Note that these are not member functions.)
|
template<class M > |
RWFixedDecimal< M > | abs (const RWFixedDecimal< M > &x) |
|
template<class M > |
bool | operator!= (const RWFixedDecimal< M > &a, const RWFixedDecimal< M > &b) |
|
template<class M > |
RWFixedDecimal< M > | operator* (const RWFixedDecimal< M > &a, const RWFixedDecimal< M > &b) |
|
template<class M > |
RWFixedDecimal< M > | operator* (const RWFixedDecimal< M > &a, const RWDecimal< M > &b) |
|
template<class M > |
RWFixedDecimal< M > | operator* (const RWDecimal< M > &a, const RWFixedDecimal< M > &b) |
|
template<class M > |
RWFixedDecimal< M > | operator* (const RWFixedDecimal< M > &a, double b) |
|
template<class M > |
RWFixedDecimal< M > | operator* (double a, const RWFixedDecimal< M > &b) |
|
template<class M > |
RWFixedDecimal< M > | operator* (const RWFixedDecimal< M > &a, int b) |
|
template<class M > |
RWFixedDecimal< M > | operator* (const RWFixedDecimal< M > &a, long b) |
|
template<class M > |
RWFixedDecimal< M > | operator* (int a, const RWFixedDecimal< M > &b) |
|
template<class M > |
RWFixedDecimal< M > | operator* (long a, const RWFixedDecimal< M > &b) |
|
template<class M > |
RWFixedDecimal< M > | operator+ (const RWFixedDecimal< M > &a, const RWFixedDecimal< M > &b) |
|
template<class M > |
RWFixedDecimal< M > | operator+ (const RWFixedDecimal< M > &a, const RWDecimal< M > &b) |
|
template<class M > |
RWFixedDecimal< M > | operator+ (const RWDecimal< M > &a, const RWFixedDecimal< M > &b) |
|
template<class M > |
RWFixedDecimal< M > | operator+ (const RWFixedDecimal< M > &a, int b) |
|
template<class M > |
RWFixedDecimal< M > | operator+ (const RWFixedDecimal< M > &a, long b) |
|
template<class M > |
RWFixedDecimal< M > | operator+ (int a, const RWFixedDecimal< M > &b) |
|
template<class M > |
RWFixedDecimal< M > | operator+ (long a, const RWFixedDecimal< M > &b) |
|
template<class M > |
RWFixedDecimal< M > | operator- (const RWFixedDecimal< M > &a, const RWFixedDecimal< M > &b) |
|
template<class M > |
RWFixedDecimal< M > | operator- (const RWFixedDecimal< M > &a, const RWDecimal< M > &b) |
|
template<class M > |
RWFixedDecimal< M > | operator- (const RWDecimal< M > &a, const RWFixedDecimal< M > &b) |
|
template<class M > |
RWFixedDecimal< M > | operator- (const RWFixedDecimal< M > &a, int b) |
|
template<class M > |
RWFixedDecimal< M > | operator- (const RWFixedDecimal< M > &a, long b) |
|
template<class M > |
RWFixedDecimal< M > | operator- (int a, const RWFixedDecimal< M > &b) |
|
template<class M > |
RWFixedDecimal< M > | operator- (long a, const RWFixedDecimal< M > &b) |
|
template<class M > |
RWFixedDecimal< M > | operator/ (const RWFixedDecimal< M > &a, const RWFixedDecimal< M > &b) |
|
template<class M > |
RWFixedDecimal< M > | operator/ (const RWFixedDecimal< M > &a, const RWDecimal< M > &b) |
|
template<class M > |
RWFixedDecimal< M > | operator/ (const RWDecimal< M > &a, const RWFixedDecimal< M > &b) |
|
template<class M > |
RWFixedDecimal< M > | operator/ (const RWFixedDecimal< M > &a, double b) |
|
template<class M > |
RWFixedDecimal< M > | operator/ (double a, const RWFixedDecimal< M > &b) |
|
template<class M > |
RWFixedDecimal< M > | operator/ (const RWFixedDecimal< M > &a, int b) |
|
template<class M > |
RWFixedDecimal< M > | operator/ (const RWFixedDecimal< M > &a, long b) |
|
template<class M > |
RWFixedDecimal< M > | operator/ (int a, const RWFixedDecimal< M > &b) |
|
template<class M > |
RWFixedDecimal< M > | operator/ (long a, const RWFixedDecimal< M > &b) |
|
template<class M > |
RWFixedDecimal< M > | operator/ (const RWFixedDecimal< M > &a, const char *b) |
|
template<class M > |
RWFixedDecimal< M > | operator/ (const char *a, const RWFixedDecimal< M > &b) |
|
template<class M > |
RWFixedDecimal< M > | operator/ (const RWFixedDecimal< M > &a, const RWDecimalPortable &b) |
|
template<class M > |
RWFixedDecimal< M > | operator/ (const RWDecimalPortable &a, const RWFixedDecimal< M > &b) |
|
template<class M > |
bool | operator< (const RWFixedDecimal< M > &a, const RWFixedDecimal< M > &b) |
|
template<class M > |
std::ostream & | operator<< (std::ostream &strm, const RWFixedDecimal< M > &x) |
|
template<class M > |
bool | operator<= (const RWFixedDecimal< M > &a, const RWFixedDecimal< M > &b) |
|
template<class M > |
bool | operator== (const RWFixedDecimal< M > &a, const RWFixedDecimal< M > &b) |
|
template<class M > |
bool | operator> (const RWFixedDecimal< M > &a, const RWFixedDecimal< M > &b) |
|
template<class M > |
bool | operator>= (const RWFixedDecimal< M > &a, const RWFixedDecimal< M > &b) |
|
template<class M > |
std::istream & | operator>> (std::istream &strm, RWFixedDecimal< M > &x) |
|
template<class M > |
long double | toDouble (const RWFixedDecimal< M > &d) |
|
template<class M > |
long int | toInt (const RWFixedDecimal< M > &d) |
|
template<class M > |
long int | toInt (const RWFixedDecimal< M > &d, RWDecimalBase::RoundingMethod m) |
|
template<class M > |
RWCString | toString (const RWFixedDecimal< M > &d) |
|
template<class M > |
RWDecimal< M > | abs (const RWDecimal< M > &d) |
|
template<class M > |
bool | operator!= (const RWDecimal< M > &a, const RWDecimal< M > &b) |
|
template<class M > |
RWDecimal< M > | operator* (const RWDecimal< M > &a, const RWDecimal< M > &b) |
|
template<class M > |
RWDecimal< M > | operator* (double a, const RWDecimal< M > &b) |
|
template<class M > |
RWDecimal< M > | operator* (const RWDecimal< M > &a, double b) |
|
template<class M > |
RWDecimal< M > | operator* (const RWDecimal< M > &a, int b) |
|
template<class M > |
RWDecimal< M > | operator* (const RWDecimal< M > &a, long b) |
|
template<class M > |
RWDecimal< M > | operator* (int a, const RWDecimal< M > &b) |
|
template<class M > |
RWDecimal< M > | operator* (long a, const RWDecimal< M > &b) |
|
template<class M > |
RWDecimal< M > | operator+ (const RWDecimal< M > &a, const RWDecimal< M > &b) |
|
template<class M > |
RWDecimal< M > | operator+ (const RWDecimal< M > &a, int b) |
|
template<class M > |
RWDecimal< M > | operator+ (const RWDecimal< M > &a, long b) |
|
template<class M > |
RWDecimal< M > | operator+ (int a, const RWDecimal< M > &b) |
|
template<class M > |
RWDecimal< M > | operator+ (long a, const RWDecimal< M > &b) |
|
template<class M > |
RWDecimal< M > | operator- (const RWDecimal< M > &a, const RWDecimal< M > &b) |
|
template<class M > |
RWDecimal< M > | operator- (const RWDecimal< M > &a, int b) |
|
template<class M > |
RWDecimal< M > | operator- (const RWDecimal< M > &a, long b) |
|
template<class M > |
RWDecimal< M > | operator- (int a, const RWDecimal< M > &b) |
|
template<class M > |
RWDecimal< M > | operator- (long a, const RWDecimal< M > &b) |
|
template<class M > |
RWDecimal< M > | operator/ (const RWDecimal< M > &a, const RWDecimal< M > &b) |
|
template<class M > |
RWDecimal< M > | operator/ (const RWDecimal< M > &a, int b) |
|
template<class M > |
RWDecimal< M > | operator/ (const RWDecimal< M > &a, long b) |
|
template<class M > |
RWDecimal< M > | operator/ (int a, const RWDecimal< M > &b) |
|
template<class M > |
RWDecimal< M > | operator/ (long a, const RWDecimal< M > &b) |
|
template<class M > |
RWDecimal< M > | operator/ (const RWDecimal< M > &a, const RWDecimalPortable &b) |
|
template<class M > |
RWDecimal< M > | operator/ (const RWDecimalPortable &a, const RWDecimal< M > &b) |
|
template<class M > |
RWDecimal< M > | operator/ (const RWDecimal< M > &a, const char *b) |
|
template<class M > |
RWDecimal< M > | operator/ (const char *a, const RWDecimal< M > &b) |
|
template<class M > |
RWDecimal< M > | operator/ (double a, const RWDecimal< M > &b) |
|
template<class M > |
RWDecimal< M > | operator/ (const RWDecimal< M > &a, double b) |
|
template<class M > |
bool | operator< (const RWDecimal< M > &a, const RWDecimal< M > &b) |
|
template<class M > |
RWvostream & | operator<< (RWvostream &strm, const RWDecimal< M > &n) |
|
template<class M > |
bool | operator<= (const RWDecimal< M > &a, const RWDecimal< M > &b) |
|
template<class M > |
bool | operator== (const RWDecimal< M > &a, const RWDecimal< M > &b) |
|
template<class M > |
bool | operator> (const RWDecimal< M > &a, const RWDecimal< M > &b) |
|
template<class M > |
bool | operator>= (const RWDecimal< M > &a, const RWDecimal< M > &b) |
|
template<class M > |
std::istream & | operator>> (std::istream &strm, RWDecimal< M > &d) |
|
template<class M > |
RWDecimal< M > | pow (const RWDecimal< M > &d, int e) |
|
template<class M > |
RWDecimal< M > | round (const RWDecimal< M > &d, int digits, RWDecimalBase::RoundingMethod m) |
|
template<class M > |
long double | toDouble (const RWDecimal< M > &d) |
|
template<class M > |
long int | toInt (const RWDecimal< M > &d, RWDecimalBase::RoundingMethod m) |
|
template<class M > |
RWCString | toString (const RWDecimal< M > &d) |
|
template<class M>
class RWFixedDecimal< M >
RWFixedDecimal classes are exact representations of decimal fractions with a fixed number of digits after the decimal point. In most ways, they behave exactly like the corresponding RWDecimal classes. The exception is that rounding automatically occurs to ensure the correct number of decimal places.
RWFixedDecimal is templatized. Three short type names are provided: RWFixedDecimal<RWMP1Int>, RWFixedDecimal<RWMP2Int>, and RWFixedDecimal<RWMP3Int>. Each type provides a different amount of precision, as described below in the Limits section. The trade-off is simple: the more precision, the slower the class.
You may also write your own RWFixedDecimal class. Throughout this section, when we refer to the RWFixedDecimal class, you can assume that it applies to any of the three provided classes, or to one you have defined.
- Synopsis
#include <rw/currency/fixeddec.h>
#include <rw/currency/mp2int.h>
The following header files are available for backward compatibility:
#include <rw/fixdec52.h>
#include <rw/fixdec64.h>
#include <rw/fixdec96.h>
- Example
#include <iostream>
#include <rw/currency/fixeddec.h>
#include <rw/currency/mp2int.h>
int main()
{
for(int i=100; i--;) bank+=penny;
bank -= 1;
std::cout << (bank==0 ? "broke!" : "whew! still solvent") << std::endl;
return 0;
}
Limits
Class RWFixedDecimal provides three static member functions that can be used to define the limits on an RWFixedDecimal object. These functions return the precision, maximum value, and minimum value:
Note that the precision returned by maxDigits() does not usually represent the number of digits in the largest possible RWFixedDecimal object. Rather, it indicates the maximum number of digits supported by that object without returning an overflow error. For example the number shown in Table 6 as the maximum value for RWFixedDecimal<RWMP2Int> has 19 digits. Notice, however, that any number larger than the 19-digit number shown will cause an overflow error because it exceeds the maximum value. Therefore, RWFixedDecimal<RWMP2Int>::maxDigits() returns 18, because that is the number of digits that will always be supported without an overflow error.
The following code snippets demonstrate when an overflow condition caused by exceeding a maximum value will occur:
Table 6 indicates the minimum and maximum values for RWFixedDecimal when T
is replaced by one of the provided multiprecision integer types:
Table 6: Minimum and maximum values for RWFixedDecimal<T>
Class | Minimum value | Max Digits |
Maximum value |
RWDecimal<RWMP3Int> | -39614081257132168796771975167 | 28 |
39614081257132168796771975167 |
RWDecimal<RWMP2Int> | -9223372036854775807 | 18 |
9223372036854775807 |
RWDecimal<RWMP1Int> | -9007199254740991 | 15 |
9007199254740991 |
Non-Numeric Values
As well as representing a decimal fraction, an RWFixedDecimal can also represent one of several non-numeric values. This concept has several uses, including, for example, representing a null entry from a database or indicating a missing value in data that is to be subjected to a statistical analysis. Currency Module supports three sorts of non-numeric values: null, missing, and NaN (Not a Number).
The result of performing arithmetic with a missing or an NaN is itself a missing or an NaN. An arithmetic operation in which one operand is a null returns either a valid number or an NaN (details are given below). Thus, missing values and NaN values propagate while null values do not.
The special static variables RWFixedDecimal::missing, RWFixedDecimal::null, and RWFixedDecimal::NaN are the prototype missing and null values; to set up a non-numeric RWFixedDecimal use these static variables, along with either the copy constructor or the assignment operator. To test for a non-numeric value, use these values, along with an equality operator. You can use the member function isNumber() to test if an RWFixedDecimal has a numeric value.
Arithmetic
For the most part, arithmetic between RWFixedDecimal objects is defined very simply: you get back an exact representation of the result of the operation. There are several special cases, however:
- Loss of precision . If the result cannot be exactly represented as an RWFixedDecimal object because it has more than 18 significant digits, then the result is set to an approximation of the true result, and the inexact error handler is called.
- Overflow/underflow . If the magnitude of the result exceeds the range of RWFixedDecimal, then the overflow error handler is called.
- Operand of missing. If one of the operands is the value missing, then the result of the arithmetic operation is also a missing.
- Operand of null. If both operands are null, the result is also null. In addition and subtraction, a null value behaves as if it were zero. In multiplication, a null behaves like a one. Dividing by a null value returns the numerator, i.e., a null in the denominator behaves like one. Using a null as the numerator in a division returns an NaN.