0

I'm facing float point precision problem in my C++ code

given double d = 32.4;

d / 0.01 == 3240.0;

gives true, while

d / 0.1 == 324.0

gives false.

But if I multiple by 10 and 100 then the result are both true.

Since 32.4, 324 and 3240 can all be represented by 64bit double without any precision loss, so this result is quite confusing to me. (I'm not very familiar with multiplier and divident operation in float point)

In my use case, I will do some conversion among different scale, by simpliy multiplying or dividing something like 0.1, 0.01, 0.05. I mean, I don't require very high precision, my operands are usually less than 6 decimals, which can be represent in 64bit double without precision loss, so I want to get consistent result. I have a guess: should I always use multiplying instead of dividing in my use case?

Ziqi Liu
  • 2,931
  • 5
  • 31
  • 64
  • 2
    if( abs((32.4 / 0.1) - 324.0) < some_small_value) std::cout << "are about equal!" << std::endl; Where some_small_value is the tolerance you're OK with. – Alex May 31 '19 at 19:29
  • The small value @Alex mentions can usually be derived from [epsilon](https://en.cppreference.com/w/cpp/types/numeric_limits/epsilon). Note the comments in the example code. – Ted Lyngmo May 31 '19 at 19:39

1 Answers1

2

You seem to be mistaken about what values a floating point type can represent.

The value 32.4 cannot be represented exactly in any binary floating point format, nor can 0.1 or 0.01. It looks like a repeating fractional number. It's the same as the value 1/3, which also can't be exactly represented in decimal format i.e. 0.3333333333333.... So any arithmetic with these values will not be exact.

The best thing you can do in your case is change the division by a floating point value into a multiplication by an integer value, ex. / 0.1 --> * 10. Even then the result won't be exact because the original value of 32.4 can't be represented exactly. You'll need to round the result to an integer value to get something exact.

dbush
  • 205,898
  • 23
  • 218
  • 273