Search code examples
c++classroundingrounding-error

Rounding numbers using the 4/5 rounding rule


I'm currently learning C++.

I have to write a simple class Money that performs calculations involving dollars and cents where arithmetic has to be accurate to the last cent using the 4/5 rounding rule.

I have never dealt before with monetary amounts so I'm having some troubles in understanding how to get the best from my class. I know that I shouldn't represent monetary amounts with float. So I use two data members for my class to store separately dollars and cents :

long int dollars
long int cents 

My problem is that I don't know when and how I should round numbers. I asked myself this question while I was trying to implement an input operator for this class. Suppose the user enters as input the values : 12.456, 45.999, 9.54.

  1. When should I round these numbers ?

  2. Should I first use them in arithmetic operations and then round the result or round them directly as they are entered into the program ?


Solution

  • Having separate dollar and cent members will just make the code more complex than necessary. Just use cents, then overload the arithmetic and assignment operators, constructor and possibly << and >> for I/O.

    Addition and subtraction are trivial, just normal integer operations scaled by 100 in this case. In general fixed-point division/multiplication requires re-scaling; you can ignore that in this case because dividing or multiplying money by money makes no sense; you may want to overload for money multiplied or divided by integers and floating-point types however (for tax, discount or interest calculation for example).

    By overloading << and >> operators for money, you can control how the cents value is input or presented - by converting it to/from dollars.cents.

    There are a number of scenarios where rounding may be necessary, but in most cases these can be handled by operator overloading. For example user input in dollars can be handled by the assignment operator and constructors, while interest, tax or share allocation calculations which may result in fractions of a cent may be handled by overloading the * and / operators (although probably internally using the assignment or constructor so that you only need the rounding in one place).

    Holding the value in cents and rounding a floating point input or intermediate dollar value to the cent, with positive/negative value handling may be achieved as follows:

    long long cents = static_cast<long long>((std::abs(dollars_fp) + 0.005) * 100) ;
    if( dollars_fp < 0 )
    {
        cents = -cents ;
    }