Rounding up a number to two decimal places in c++

Viewed 389

I'm wishing to round up a float variable to two decimal places regardless of what the float is. My current code is shown below:

void MainMethods::convert(float& floatValue, string numericString) 
{
    floatValue = stof(numericString); //converts string to a float
    floatValue = ceil(floatValue * 100.00) / 100.00;
}

Which just converts the string to a float and then after will round up using ceil(). This works fine for when I have either whole numbers, or numbers that go beyond 3 decimals. However when inputting a value of 2 decimals, such as 567.56, the value then returns 567.57 instead. How do I stop this?

1 Answers

The problem you are seeing is because floating point values can not represent all non integer values exactly. What Every Computer Scientist Should Know About Floating-Point Arithmetic

What you have to remember is that all bits that represent values between 1 and 0 are still powers of 2 (though negative powers).

2^-1    => 0.5
2^-2    => 0.25
2^-3    => 0.125
2^-4    => 0.0625
etc.

Thus to represent an floating point value you need to keep adding these smaller and smaller values until you get close to the value you want.

Looking at your floating point Number:

567.57

Float remainder   Rep         Value
.57               => 2^-1  => 0.5
.07               => 2^-4  => 0.0625
.0075             => 2^-8  => 0.00390625
.00359375         => 2^-9  => 0.001953125
.001640625        etc..

Note: That is not exactly how it is done but to demonstrate the issue.

As a result, you will get rounding issues whenever you use any type of floating point value. This is particularly noticeable when you print the value in base 10 on some stream, but it happens for every operation.

Because you are using 2 decimal places I assume you are trying to represent some form of monetary value?

I would keep the number as an integer.
That way you can represent it exactly. Then you can add a printing function to add the decimal place.

#include <string>
#include <iostream>
#include <iomanip>

class Money
{
    long  value;   // in cent.
    public:
        Money(std::string const& value)
            : value(stof(numericString) * 100)
        {}
        friend std::ostream& operator<<(std::ostream& stream, Money const& money)
        {
            stream << (money.value / 100) << "."
                   << std::setw(2) << std::setfill('0') << (money.value % 100);
            return stream;
       }
};

int main()
{
    Money   myCurrentAccount("1000000.56");

    std::cout << myCurrentAccount << "\n";
}
Related