0

I made a simple test to see how the round off error can be amplified in the computation. This code below

int main(int argc, char *argv[])
{
    double a = 1.1237194475545454312;
    double b = 123124.65464646545467897;
    double c = 1.23212412412546464318794e22;

    double A = (a + b) * c;
    double B = a*c + b*c;
    double diff = A - B;

    std::cout << "diff: " << std::setprecision(10) << std::scientific << diff << std::endl;
    return 0;
}

gives result:

diff: 2.7487790694e+11

However, when change c to double c = 1.23212412412546464318794e23;, the result is

diff: 0.0000000000e+00

What could possibly go wrong with the first evaluation?

The compiler is g++ 11.3.0

kstn
  • 537
  • 4
  • 14
  • There's nothing going wrong. Floating-point arithmetic is different from the real number arithmetic that all of us are used to. In fact, "round off error" reflects exactly this problem: floating-point arithmetic does **exactly** what it does, and "round off error" is about the difference between what it does and what you expect. – Pete Becker Mar 26 '23 at 18:14
  • 1
    If you use `long double` there is enough in-built precision - live - https://godbolt.org/z/hKevbbfzf . The issue will return when you need more precision than `long double` can provide. – Richard Critten Mar 26 '23 at 18:19
  • kstn, due to rounding errors you end up with `A = 1.51706241826366657220e+27` and `B = 1.51706241826366629732e+27`. Compare the last few digits of mantissae. That's why your diff is non-zero. In the 2nd case there happens to be no rounding error and you get 0. – Super-intelligent Shade Mar 26 '23 at 19:17
  • @Super-intelligentShade why the second case has no rounding error? – kstn Mar 26 '23 at 20:55
  • Because the resulting numbers in `A` and `B` happen to be perfectly represented by the [IEEE 754](https://en.wikipedia.org/wiki/Double-precision_floating-point_format) format. If you look at this example: https://godbolt.org/z/PbKcffWGP. Only `0`, `.5` and `1` can be perfectly represented by IEEE 754. The other 8 numbers aren't. – Super-intelligent Shade Mar 26 '23 at 21:14
  • Print out `A` and `B` with higher precision. Then you'll see more clearly what's going on. – Paul Sanders Mar 26 '23 at 21:21

0 Answers0