SIGFPE Shenanigans

use*_*797 4 c++ sigfpe

我重复相同的计算两次,但在一次我得到一个浮点异常,而在另一个我没有.

#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;
}
Run Code Online (Sandbox Code Playgroud)

我在g ++和clang ++上测试了它,并在两者中得到了以下输出

y = 4.76299e-07
Floating point exception
Run Code Online (Sandbox Code Playgroud)

这是怎么回事?

kur*_*eko 5

这是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;
}
Run Code Online (Sandbox Code Playgroud)

默认情况下,此异常显然已禁用,否则您根本无法进行任何浮点计算.