SIGFPE Shenanigans

I repeat the same calculation twice, but in one I get a floating point exception, and 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 in both g ++ and clang ++ and got the following output in both

y = 4.76299e-07
Floating point exception

What's happening?

+4
source share
2 answers

The problem is

feenableexcept(-1);

This set of FPE exceptions for all possible cases includes inaccurate results (which are very common in floating point operations). You really shouldn't use the number here, but instead use the provided macros to set the bits you need.

Replacement

feenableexcept(FE_INVALID   | 
               FE_DIVBYZERO | 
               FE_OVERFLOW  | 
               FE_UNDERFLOW);

solves the problem for me.

At

feenableexcept(FE_INVALID   | 
               FE_DIVBYZERO | 
               FE_OVERFLOW  | 
               FE_UNDERFLOW |
               FE_INEXACT);

SIGFPE. , FE_INEXACT .

, SIGFPE, , ( ). , .

+4

FE_INEXACT.
, x, 1/(24.3*24.0*3600.0), , double .

, x - 1.0, , () .

, /.

#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;
}

, .

+5

Source: https://habr.com/ru/post/1525242/


All Articles