0
#include <iostream>

using namespace std;

int
main ()
{
  double a = 0.01;
  double b = 45.01 - 45;
  double c = b;

  if (a == c)
    cout << "a is 0.01" << '\n';
  else
    cout << "a is not 0.01" << '\n';

  return 0;
}

Running the above code gives the output "a is not 0.01" instead of "a is 0.01". I'm not getting why if-statement is messing up the double values of a and c? Here why and a is not equal to b and c? What should I do to get the desired output of "a is 0.01"?

  • In general, floating point arithmetic is not exact because of rounding errors, `a` is not equal to `c` but it is **almost** equal to `c`. – john Apr 25 '20 at 10:43
  • Wait until you add up a large number of doubles. You "should" sort them first to make sure you get a more accurate result otherwise you can loose "more" precision. :-) – Martin York Apr 25 '20 at 20:42

1 Answers1

0

This is a floating point arithmetic problem.

Running this:

#include <iostream>

using namespace std;

int main () {
  double a = 0.01;
  double b = 45.01 - 45;
  double c = b;
  std::cout << a-c << std::endl;
  return 0;
}

Will give this output:

1.98973e-015

This is because of the way floating points are represented in C++.

One thing you can do is to round the result by using the round() function (c++11 or newer compiler) or by casting the result to an integer with few modifications.

I prefer the casting option because in certain cases using the round() function will need a bit more modification if the result is negative.

  double d = int( (a - c) * 100) / 100;
  std::cout << d << std::endl;

Will give the following output:

  0

Therefore, this will do the trick:

#include <iostream>
using namespace std;

int main () {
  double a = 0.01;
  double b = 45.01 - 45;
  double c = b;

  double d = int( (a - c) * 100) / 100;

  if (!d) // equivalent to (d == 0)
    std::cout << "a is 0.01" << std::endl;
  else
    std::cout << "a is not 0.01" << std::endl;

  return 0;
}

You can read the followings to get a better understanding of the issue -

What Every Computer Scientist Should Know About Floating-Point Arithmetic

Comparing Floating Point Numbers, 2012 Edition

You can also go over the answers in this question from which I have gotten the recommended articles.

Edit: As Artyer pointed out, this is a way of rounding up the value. If you use this method you need to replace the '100' int:

double d = int( (a - c) * 100) / 100;

with 10^x, where x will be the decimal precision you want to have.

Elia
  • 422
  • 6
  • 11
  • `int((a - c) * 100) / 100 == 0` is a really round about way of saying `std::abs(a - c) < 0.01`, which is the de facto way to check for "close enoughness" – Artyer Apr 25 '20 at 15:28
  • I have edited my answer. I agree that this is still kind of a work around, do you know if there is a better way of solving this problem? – Elia Apr 25 '20 at 20:40