Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SIGFPE Shenanigans

Tags:

c++

sigfpe

I'm repeating the same calculation twice, but in one I get a floating point exception while in the other I don't.

#include <iostream>
#include <cmath>
#include <fenv.h>

using namespace std;

int main(void)
{
  feenableexcept(-1);

  double x,y,z;

  x = 1.0;

  y = (1.0/(24.3*24.0*3600.0))*x;
  cout << "y = " << y << endl;

  z = x/(24.3*24.0*3600.0);
  cout << "z = " << z << endl;

  return 0;
}

I tested it on both g++ and clang++ and got the following output in both

y = 4.76299e-07
Floating point exception

What's going on?

like image 991
user2535797 Avatar asked Jan 11 '23 06:01

user2535797


1 Answers

That's the FE_INEXACT exception.
It means x multiplied by the constant 1/(24.3*24.0*3600.0) computed at compile time cannot be converted to double without loss of precision.

The first operation does not raise this exception because x is 1.0, which has an exact representation, and the constant has already been converted to some (inexact) double representation at compile time.

Since floating point exceptions handling is not standardized, this might go unnoticed on other compilers/platforms.

#include <iostream>
#include <cmath>
#include <fenv.h>

using namespace std;

int main(void)
{
  feenableexcept(FE_INEXACT); // comment this line out and the exception is gone

  double x,y,z;

  x = 1.0;

  y = (1.0/(24.3*24.0*3600.0))*x;
  cout << "y = " << y << endl;
  z = x/(24.3*24.0*3600.0);      // <-- FE_INEXACT exception
  cout << "z = " << z << endl;

  return 0;
}

This exception is obviously disabled by default, or else you could hardly do any floating point computation at all.

like image 170
kuroi neko Avatar answered Jan 24 '23 06:01

kuroi neko