Currency Module User’s Guide : Chapter 4 Money and Calculations : Mixed-Currency Calculations
Mixed-Currency Calculations
It is very possible that your applications will need to add money values of different currencies. The Currency Module provides a money calculator class in the class RWMoneyCalculator<T>.
Before you can use a money calculator class, you must consider and possibly set two policies. The first is the conversion policy, which determines what currency will be used for the result of a mixed-currency calculation. The second is the rounding policy, which determines how the money calculator should round decimal places.
Setting the Conversion Policy
Whenever your application performs arithmetic operations involving two or more different currencies, one or more currency conversions must take place. A conversion policy determines how the money calculator will express the result of its calculation.
There are four conversion policies available to the money calculator class:
No Conversion. An operations performed on monies of different currencies throws an exception.
Base Currency Conversion. When arithmetic operations are performed on monies of different currencies, both operands are converted to a base currency. After performing the calculation, the money calculator returns the result in the base currency.
Target Currency Conversion. When arithmetic operations are performed on monies of different currencies, the source operand (first argument) is converted to the target operand (second argument) currency. After performing the calculation, the money calculator returns the result in the target currency.
Source Currency Conversion. When arithmetic operations are performed on monies of different currencies, the target operand (second argument) is converted to the source operand (first argument) currency. After performing the calculation, the money calculator returns the result in the source currency.
A money calculator object’s currency conversion type can be set at construction. It can also be set or changed using the setConversionType() member function.
In addition to setting the conversion type, you must also associate an RWExchangeFactory object with the calculator object. The RWExchangeFactory provides the exchange rate table that is used to perform the conversion. For more information on exchange rates and exchange rate tables, see “Exchange Rates and Exchange Rate Tables.” The following example shows how you construct an RWMoneyCalculator<T> and some money objects, then perform mixed-currency calculations:
 
typedef RWDecimal< RWMP2Int > Decimal;
RWExchangeRateTable table;
.
.
.
RWExchangeFactory<Decimal> factory( table );
.
.
.
RWMoneyCalculator<Decimal> calculator( factory,
RWMoneyCalculator<Decimal>::target );
 
RWMoney<Decimal> lira(Decimal("12823"), "ITL" );
RWMoney<Decimal> marks(Decimal("1.26"), "DEM" );
 
RWMoney<Decimal> sum = calculator.add( lira, marks );
 
calculator.setConversionType( RWMoneyCalculator<Decimal>::base );
calculator.setBaseCurrency( "USD" );
 
sum = calculator.add( lira, marks );
.
.
.
Setting the Precision and Rounding Method
In addition to setting the conversion policy, you must set a rounding policy and a precision for the calculator. The precision specifies how many digits to the right of the decimal points should be reported.
You can also set a comparison digit that lets you control when rounding up or down occurs. The comparison digit works only with plain or bankers rounding. As described below, the plain and bankers rounding methods always compare the digit to the right of the precision position to the comparison digit and then increment the digit in the precision position, or leave it as is, based on the comparison. The default comparison digit is 5.
Rounding a negative number is equivalent to rounding the absolute value of the negative number, then multiplying the result by negative one.
The rounding policies available for RWMoneyCalculator are:
Round up. If the digits the right of the specified precision decimal place are non-zero, add one to the digit at the specified precision decimal place, then truncate any digits to the right.
Round down. Truncate all digits to the right of the specified precision decimal place.
Plain. If the digit one to the right of the specified precision decimal place is greater than a comparison digit, increase the digit at the precision position by one and truncate all numbers to the right. Otherwise, truncate all digits to the right of the precision position. For example, if the precision is 1 and the comparison digit is 5, then 2.35 and 2.35001 both round to 2.3, and 2.37 rounds to 2.4. If you set the comparison digit to 3, however, 2.35, 2.35001 and 2.37 all round to 2.4.
Bankers. Bankers rounding is the same as plain rounding except that in the case of a tie, increment the digit at the specified precision position if necessary to make it an even number. A tie occurs when the digit to the right of the specified precision position equals the comparison digit, and there are no following non-zero digits. For example, when rounding to one decimal place with the default comparison digit of 5, the number 2.45 represents a tie. It rounds to 2.4, because the 4 at the precision position is an even number. 2.45000 is also a tie and also rounds to 2.4. However, 2.45001 is not a tie, so it rounds to 2.5 based on the rules for plain rounding.
Don’t round. No rounding will occur, and precision is ignored.
Table 3 shows the effects of the rounding policies:
Table 3 – Methods of rounding 
Method
1.245
1.25
1.251
1.255
1.259
-1.259
1.26500
1.26501
UP
precision = 2
1.25
1.25
1.26
1.26
1.26
-1.26
1.27
1.27
DOWN
precision = 2
1.24
1.25
1.25
1.25
1.25
-1.25
1.26
1.26
PLAIN
precision = 2
comparison = 5
1.24
1.25
1.25
1.25
1.26
-1.26
1.26
1.26
BANKERS
precision = 2
comparison = 5
1.24
1.25
1.25
1.26
1.26
-1.26
1.26
1.27
NO ROUNDING
1.245
1.25
1.251
1.255
1.259
-1.259
1.26500
1.26501
The default constructor for an RWMoneyCalculator creates a money calculator without a rounding method or a currency conversion policy. For other constructors, the default rounding method is noRounding, the default precision is 2, and the default comparison digit is 5. RWMoneyCalculator provides member functions setAccuracy(), setRoundDigit(), and setRoundMethod() to set the precision, comparison digit, and rounding method for the object.