1

I am trying to subtract a small double number from a large double number in C++. Here is my code

int main() 
{
double a=166666166667000000.000000;
double b=1.0;
double c=4.0;
double d=10.0;

double ans_b=a-b;
double ans_c=a-c;
double ans_d=a-d;

printf("%f\n%f\n%f\n",ans_b,ans_c,ans_d);
return 0;
}

This Code is giving me following output -

166666166667000000.000000
166666166667000000.000000
166666166667000000.000000

However, all three are supposed to be different. Why does subtraction with double type behaves this way?

meow
  • 307
  • 4
  • 16
  • 2
    That's because double has finite precision. – piotrekg2 Nov 17 '14 at 16:44
  • 1
    this is not a duplicate of the mentioned question. – pm100 Nov 17 '14 at 16:48
  • How many bits do you need to represent 166666166667000001? How many bits are there in a `double`? How many of them are mantissa? – n. m. could be an AI Nov 17 '14 at 16:48
  • 1
    A 64-bit double has about 15 decimal digits of precision; `66666166667000001` is outside of that range of precision. Using very large and very small values in the same calculation is problematic. – John Bode Nov 17 '14 at 17:26
  • To add two floating point numbers, the software (or co-processor) has to keep halving the mantissa of the smaller one and increasing its exponent, to align them so they have the same exponent. They can then be added. In your example, the small values will get shifted down to 0 before the exponents match. – Weather Vane Nov 17 '14 at 18:53

1 Answers1

1

166666166667000000 and 10 are both exactly representable in double. The real number arithmetic result of the subtraction, 166666166666999990, is not. The largest double that is strictly less than 166666166667000000 is 166666166666999968.

166666166666999990 is closer to 166666166667000000 than to 166666166666999968, so 166666166667000000 is the round-to-nearest double result of the subtraction.

If you are just doing the one small number subtraction, you can ignore the issue. If you are doing enough small number subtracts that their cumulative effect matters, you need to rearrange your calculation.

Patricia Shanahan
  • 25,849
  • 4
  • 38
  • 75