如果你正在构建一个计算器界面并且想要处理浮点异常,你应该:
你将没有任何帮助,所以你必须手动实现。示例:
double mul(double a, double b, int *status) {
#pragma STDC FENV_ACCESS ON
fexcept_t flags;
int sv_status, f_status = -1;
double resul;
sv_status = fegetexceptflag(&flags, FE_ALL_EXCEPT) != 0; /* save flags */
if (sv_status == 0) {
f_status = feclearexcept(FE_ALL_EXCEPT); /* clear all fp exception con
ditions */
}
resul = a * b;
if (f_status == 0) {
*status = fetestexcept(FE_ALL_EXCEPT); /* note conditions */
}
if (sv_status == 0) {
fesetexceptflag(&flags, FE_ALL_EXCEPT); /* restore initial flags */
}
return resul;
}
演示:
int main ()
{
double d2, d3, d4;
int status;
double d = 1e100;
feraiseexcept(FE_OVERFLOW | FE_INEXACT);
status = fetestexcept(FE_ALL_EXCEPT);
printf("initial status : %x\n", status);
d2 = mul(3., 4., &status);
printf("resul 3 * 4 : %g - status %x (%x)\n", d2,
status, fetestexcept(FE_ALL_EXCEPT));
d2 = mul(d, d, &status);
printf("resul d * d : %g - status %x (%x)\n", d2,
status, fetestexcept(FE_ALL_EXCEPT));
d2 = mul(d2, d, &status);
printf("resul d *d *d : %g - status %x (%x)\n", d2,
status, fetestexcept(FE_ALL_EXCEPT));
d2 = mul(d2, d, &status);
printf("resul d *d *d*d : %g - status %x (%x)\n", d2,
status, fetestexcept(FE_ALL_EXCEPT));
d2 = mul(d2, d, &status);
printf("resul d *d *d*d*d : %g - status %x (%x)\n", d2,
status, fetestexcept(FE_ALL_EXCEPT));
return 0;
}
给:
initial status : 28
resul 3 * 4 : 12 - status 0 (28)
resul d * d : 1e+200 - status 20 (28)
resul d *d *d : 1e+300 - status 20 (28)
resul d *d *d*d : inf - status 28 (28)
resul d *d *d*d*d : inf - status 0 (28)
这意味着mul:
由于此代码仅使用 C 规范中定义的宏和函数,因此它应该适用于任何符合 C99 的编译器。
现在由您来实际处理标志。
参考:ISO/IEC 9899:201x (ISO C11) Committee Draft
注意:Clang(至少)发出警告说它忽略了编译指示 STDS FENV_ACCESS 但它工作正常