0

I am trying to round a decimal to 2 digits. To do so, I am multiplying my decimal by 100 and using the floor() function (because I need to round down so that fractions of a penny - I am working with finances - are not counted), then dividing that number by 100.

In the case of the issue, I am doing 86/100 and it is returning 85.99999999999 and I am not sure why.

int main() 
{
    double balance = 133.45;
    double apr = 7.8;
    double newBalance = balance * pow((1+((apr/100)/1)), (1));
    double interest = newBalance - balance;
    double month = interest / 12;
    double total = floor(month * 100) / 100;
    return 0;
}

I have looked through other sources online, and I haven't been able to find out why.

Is it an edge case with the floor() function? This is probably a dumb question, but I couldn't find an answer.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • 8
    This seems apropos: [**Is floating point math broken?**](https://stackoverflow.com/questions/588004/is-floating-point-math-broken) – Andrew Henle Nov 07 '22 at 23:00
  • The result of dividing two `double`s is a `double`. If you **display** the result with default precision you get six digits. If you only want to **see** two digits, use an I/O manipulator (`std::setprecision`) to tell the output stream how many digits to show. That has nothing to do with how the `double` is stored; it has more than two digits. – Pete Becker Nov 07 '22 at 23:06
  • 4
    *"I need to round down so that fractions of a penny (I am working with finances) are not counted"* Then, maybe, you should store the number of pennies as (long long) integers and use those instead of floating-point numbers. *"I am trying to round a decimal to 2 digits"* note that `double` have usually [radix](https://en.cppreference.com/w/cpp/types/numeric_limits/radix) 2, they are stored as binary not as [decimal floating-point](https://en.wikipedia.org/wiki/Decimal64_floating-point_format). – Bob__ Nov 07 '22 at 23:07
  • 4
    NEVER use floating-point values when doing math with currencies. ALWAYS use whole integers instead. Otherwise rounding issues WILL creep in and throw off your results. Convert whole integers to decimals only for display purposes. – Remy Lebeau Nov 08 '22 at 00:28
  • The basic reason is that a floating point type (with a base 2 mantissa) cannot exactly represent values like `0.1` and `0.01` or (with some exceptions) multiples of them. For example, a floating point type cannot represent the value `7.8` exactly (only an approximation is stored) although it can represent some particular values such as `0.5` and `0.25` exactly. To avoid having errors propagate through your calculations, you should *not* use floating point variables in any calculations involving monetary values *at all*. – Peter Nov 08 '22 at 00:38

0 Answers0