Floating Point Trickyness (2) —- select Is’t Broken, Is It?

Posted on 14 May 2009  •  Permalink  •  Category c++

In my previous post I talked about rounding errors with floating point numbers. If you work with real numbers and computers, sooner or later, just like others before you, you will conclude that computers suck at math.

But what if you have a compiler that sucks at math? I recently experienced that that can give you severe headaches. Consider the following code snipplet:

#include <cmath>

int main(int argc, char **argv)
{
  double x = std::sqrt(1.0 - std::pow(2.0, 2));
}

Taking the square root from -3, should be NaN, and if you try this with a recent version of g++, you will get NaN. Everything fine. However, if you try this with g++ 3.4.3 on Sparc, with -O2 turned on, the answer is, well, actually, there is no answer. At least not after 12 hours; our test that includes the same formula as in the above code snipplet ran for more than 12 hours without terminating. That’s how I found this problem. From an infinitely looping test.

It took a while to figure out what was going on since the original problem line was of course bigger including several more mathematical expressions. After breaking it down I could isolate the problem to the simplified expression as shown above.

Even in the strangest cases, usually still “select Isn’t Broken” [1]. But in this (very rare) case it is.

[1]“It is rare to find a bug in the OS or the compiler, or even a third-party product or library. The bug is most likely in the application.” —- From the Pragmatic Programmer, one of the most influential programming books I read.