RWFixedDecimal RWDecimal RWDecimalBase
#include <rw/money/fixeddec.h> /* for RWFixedDecimal<T> */ #include <rw/money/mp2int.h> /* For RWMP2Int */ RWFixedDecimal<RWMP2Int> dollarAccount(0,2) = "0.01"; // initialize to zero then set to 2 decimal places
The following header files are available for backward compatibility:
#include <rw/fixdec52.h> /* RWFixedDecimal52 */ #include <rw/fixdec64.h> /* RWFixedDecimal64 */ #include <rw/fixdec96.h> /* RWFixedDecimal96 */
RWFixedDecimal<T> 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<T> classes. The exception is that rounding automatically occurs to insure the correct number of decimal places.
RWFixedDecimal<T> 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<T> class. Throughout this section, when we refer to the RWFixedDecimal<T> class, you can assume that it applies to any of the three provided classes, or to one you have defined.
#include <iostream.h> #include <rw/money/fixeddec.h> #include <rw/money/mp2int.h> main(){ RWFixedDecimal<RWMP2Int> penny = "0.01"; RWFixedDecimal<RWMP2Int> bank = 0; for(int i=100; i--;) bank+=penny; // deposit 100 pennies bank -= 1; // withdraw a buck cout << (bank==0 ? "broke!" : "whew! still solvent") << endl; return 0; }
Class RWFixedDecimal<T> provides three static member functions that can be used to define the limits on an RWFixedDecimal<T> object. These functions return the precision, maximum value, and minimum value:
int RWFixedDecimal<T>::maxDigits() // precision RWFixedDecimal<T> RWFixedDecimal<T>::maxValue() // maximum value RWFixedDecimal<T> RWFixedDecimal<T>::minValue() // minimum value
Note that the precision returned by maxDigits() does not usually represent the number of digits in the largest possible RWFixedDecimal<T> 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 12 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. There fore, 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:
\\ Set max to maximum value: RWFixedDecimal<RWMP1Int>max = RWFixedDecimal<RWMP1Int>::maxValue() \\ Add 1 to max to generate an overflow error: RWFixedDecimal<RWMP1Int>tooBig = max + RWFixedDecimal<RWMP1Int>(1) \\ Set min to minimum value: RWFixedDecimal<RWMP1Int>min = RWFixedDecimal<RWMP1Int>::minValue() \\ Subtract 1 from min to generate an overflow error: RWFixedDecimal<RWMP1Int>tooSmall = min-RWFixedDecimal<RWMP1Int>(1)
Table 6 indicates the minimum and maximum values for RWFixedDecimal<T> when T is replaced by one of the provided multi-precision integer types:
Class | Minimum value | Max Digits |
Maximum value | ||
RWDecimal<RWMP3Int> |
-39614081257132168796771975167 |
28 |
39614081257132168796771975167 | ||
RWDecimal<RWMP2Int> |
-9223372036854775807 |
18 |
9223372036854775807 | ||
RWDecimal<RWMP1Int> |
-9007199254740991 |
15 |
9007199254740991 |
As well as representing a decimal fraction, an RWFixedDecimal<T> 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. Money.h++ 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, missings and NaNs propagate while nulls 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<T> 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<T> has a numeric value.
For the most part, arithmetic between RWFixedDecimal<T> 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<T> object because it has more than 18 significant digits, then the result is set to an approximation of the true result, and the precisionLoss error handler is called.
Overflow/underflow. If the magnitude of the result exceeds the range of RWFixedDecimal<T>, 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.
RWFixedDecimal();
Constructs an RWFixedDecimal<T> with a value of null.
RWFixedDecimal(const RWFixedDecimal&);
Copy constructor. Constructs an RWFixedDecimal<T> that is a copy of the argument.
RWFixedDecimal(const RWDecimal&);
Copy constructor. Constructs an RWFixedDecimal<T> that represents the same value as the parameter. The number of decimal places is fixed to be the same as the parameter.
RWFixedDecimal(const char *s);
Constructs an RWDecimal<T> from the null terminated character string s. Since we write numbers using base 10 and the RWDecimal<T> class stores numbers using base 10, the number constructed is an exact representation of the string. If the string cannot be successfully parsed as a number, the RWDecimal<T> is initialized to null. If the number in the string cannot be exactly represented (for example, it has too many significant digits) then the appropriate error handler (either the inexact or overflow handler) is called. The string may contain embedded commas to separate groups of digits and may have a leading dollar sign. Negatives can be indicated with a negative sign or by using parentheses. A technical description of the exact input grammar allowed is given in the "Technical Notes" section of this manual.
RWFixedDecimal(long int x); RWFixedDecimal(int x);
Constructs an RWFixedDecimal<T> with value x. The explicit integer constructors prevent initializations from 0 from being ambiguous. Without the int constructor, the compiler would not know whether to convert 0 to a const char* or a long int.
RWFixedDecimal(long int x, int e); RWFixedDecimal(int x, int e);
Constructs an RWFixedDecimal<T> with value x*10-e where e represents the number of digits after the decimal point.
int decimalPlaces() const;
Returns the number of digits to the right of the decimal point.
RWBoolean isNumber() const;
Returns TRUE if self represents a decimal fraction; returns FALSE if self is not a representation of a number: for example, self is a null or missing value.
void restoreFrom(RWvistream&); void restoreFrom(RWFile&);
Restores value of self from a virtual stream or an RWFile. The virtual streams and RWFile classes are provided with Rogue Wave's Tools.h++ class library. These functions require that you link in the Tools.h++ library.
void saveOn(RWvostream&) const; void saveOn(RWvostream&) const;
Stores value of self to a virtual stream, or in binary format to an RWFile. The virtual streams and RWFile classes are provided with Rogue Wave's Tools.h++ class library. These functions require that you link in the Tools.h++ library.
RWFixedDecimal<T>& operator=(const RWFixedDecimal<T>&);
Sets value of self equal to the value of the argument.
RWFixedDecimal<T>& operator+=(const RWFixedDecimal<T>&); RWFixedDecimal<T>& operator-=(const RWFixedDecimal<T>&); RWFixedDecimal<T>& operator*=(const RWFixedDecimal<T>&); RWFixedDecimal<T>& operator/=(const RWFixedDecimal<T>&);
Performs the operation between self and the argument, and stores the results in self.
RWFixedDecimal<T> operator+(const RWFixedDecimal<T>&); RWFixedDecimal<T> operator-(const RWFixedDecimal<T>&);
Returns the result of applying the unary operator.
RWFixedDecimal<T> operator+(const RWFixedDecimal<T>&, const RWFixedDecimal<T>&); RWFixedDecimal<T> operator-(const RWFixedDecimal<T>&, const RWFixedDecimal<T>&); RWFixedDecimal<T> operator*(const RWFixedDecimal<T>&, const RWFixedDecimal<T>&); RWFixedDecimal<T> operator/(const RWFixedDecimal<T>&, const RWFixedDecimal<T>&);
These arithmetic operators have their conventional meanings.
RWBoolean operator<(const RWFixedDecimal<T>&,const RWFixedDecimal<T>&); RWBoolean operator>(const RWFixedDecimal<T>&,const RWFixedDecimal<T>&); RWBoolean operator<=(const RWFixedDecimal<T>&,const RWFixedDecimal<T>&); RWBoolean operator>=(const RWFixedDecimal<T>&,const RWFixedDecimal<T>&);
The relational operators have their conventional meanings. If one (or both) of the operands is null or missing, then the result of the operator is undefined.
RWBoolean operator==(const RWFixedDecimal<T>&,const RWFixedDecimal<T>&); RWBoolean operator!=(const RWFixedDecimal<T>&,const RWFixedDecimal<T>&);
The equality operator returns TRUE if the two operands are exactly the same, and FALSE otherwise. The not equal operator, !=, does the complement.
istream& operator>>(istream&, RWFixedDecimal<T>&);
Reads an RWFixedDecimal<T> from an input stream. The format expected is (-xxx.yyy) where the xxx and yyy are integers (which may begin with zeros) and all the parts - parentheses, minus sign, xxx, decimal point, and yyy - are optional. Since we write numbers using base 10, and the RWFixedDecimal<T> class stores numbers using base 10, the number constructed is an exact representation of the input.
ostream& operator<<(ostream&, const RWFixedDecimal<T>&);
Writes an RWFixedDecimal<T> to an output stream. Output is written in the form -xxx.yyy where the xxx and yyy are integers and only the necessary parts are written. For more elaborate formatting, use an RWDecimalFormat object.
RWFixedDecimal<T> abs(const RWFixedDecimal<T>& x);
Returns the absolute value of x.
RWFixedDecimal<T> pow(const RWFixedDecimal<T>& x, int n);
Returns x raised to the exponent n. This computation is likely to cause a loss of precision (and a corresponding call to the precision error handler) if n is at all large and x has any decimal places.
RWFixedDecimal<T> round(const RWFixedDecimal<T>& x, int n,
RWFixedDecimalBase::ROUNDING=PLAIN);
Returns x rounded to n decimal places. The method of rounding is controlled by the optional last parameter as follows:
Method | Description | 1.25 | 1.35 | 1.251 |
PLAIN |
Rounds away from zero on a tie |
1.3 |
1.4 |
1.3 |
UP |
Always rounds away from zero |
1.3 |
1.4 |
1.3 |
DOWN |
Always rounds toward zero |
1.2 |
1.3 |
1.2 |
TRUNCATE |
Same as DOWN |
1.2 |
1.3 |
1.2 |
BANKERS |
On a tie, round so last digit is even |
1.2 |
1.4 |
1.3 |
The last three columns indicate the result of rounding three example numbers to one decimal place.
long double toDouble(const RWFixedDecimal<T>& x);
Converts the argument to a double precision value close to its true value.
long int toInt(const RWFixedDecimal<T>& x, RWFixedDecimalBase::ROUNDING=PLAIN);
Converts the argument to an integer. The method of rounding is controlled by the optional last parameter, as described in detail above in the description of the global function round.
RWCString toString(const RWFixedDecimal<T>&);
Converts an RWFixedDecimal<T> to a string. The string has the form xxx.yyy where the xxx and yyy are integers and only the parts necessary are written. For more elaborate formatting, use an RWDecimalFormat object.
static RWFixedDecimal<T> from(double); static RWFixedDecimal<T> from(long double);
Converts a floating point value to an RWDecimal. The results may be inexact.
static int maxDigits();
Returns the maximum number of digits that an RWDecimal<T> of the indicated type can contain.
static int maxDigits();
Returns the maximum number of digits that an RWFixedDecimal<T> of the indicated type is guaranteed to represent without overflow. In most cases, an RWFixedDecimal<T> can represent some numbers of length actualDigits, where actualDigits=maxDigits() + 1. For example, the maxDigits() value for class RWDecimal<T> is 18, even though the number of digits in the maxValue() for the class is 19.
static RWDecimal<T> maxValue();
Returns the maximum value that can be represented by this class. The maximum value +1 will always generate an overflow error.
static RWDecimal<T> minValue();
Returns the minimum value that can be represented by this class. The minimum value -1 will always generate an overflow error.
static void setInexactHandler(void (*)(const RWDecimalInexactErr<T>&));
Sets the function that is called when an "inexact" error occurs. This type of error most often indicates use of an arithmetic operation that will cause loss of precision in the result. The default error handler, defaultInexactHandler, prints an error message, but does not throw an exception.
static void setOverflowHandler(void (*)(const RWDecimalOverflowErr<T>&));
Sets the function that is called when an "overflow" error occurs. This type of error most often indicates the use of an arithmetic operation that will cause a result larger than can be stored. The default error handler, defaultOverflowHandler, simply throws the error object as a C++ exception.
RWFixedDecimal<T> null; RWFixedDecimal<T> missing; RWFixedDecimal<T> NaN;
The prototype non-numeric values. Use these to set an RWFixedDecimal<T> to a non-numeric value or to test for a specific non-numeric value.
©Copyright 1999, Rogue Wave Software, Inc.
Send mail to report errors or comment on the documentation.