正如问题所述,我正在使用 MIPSPRo C 编译器,并且我有一个操作将为分子和 denom 都为零的某些数据集返回 NaN。我如何防止这种情况发生?
问问题
900 次
4 回答
9
在带有 MIPSPro 编译器的 SGI 系统上,您可以使用sigfpe.h
. 碰巧,零除以零就是这样一种情况:
#include <stdio.h>
#include <sigfpe.h>
int main (void) {
float x = 0.0f;
(void) printf("default %f / %f = %f\n", x, x, (x / x));
invalidop_results_[_ZERO_DIV_ZERO] = _ZERO;
handle_sigfpes(_ON, _EN_INVALID, 0, 0, 0);
(void) printf("handled %f / %f = %f\n", x, x, (x / x));
return 0;
}
正在使用:
arkku@seven:~/test$ cc -version
MIPSpro Compilers: Version 7.3.1.3m
arkku@seven:~/test$ cc -o sigfpe sigfpe.c -lfpe
arkku@seven:~/test$ ./sigfpe
default 0.000000 / 0.000000 = nan0x7ffffe00
handled 0.000000 / 0.000000 = 0.000000
如您所见,设置_ZERO_DIV_ZERO
结果会更改相同除法的结果。同样,您可以处理常规除以零(例如,如果您不希望结果为无穷大)。
当然,这些都不是标准的。在每次除法之后检查 NaN 会更便携,甚至更好地在之前检查零。C99 提供了对 中的浮点环境的一些控制fenv.h
,但我认为没有任何适合此的可用。无论如何,我的旧 MIPSPro 不支持 C99。
于 2010-04-01T23:35:44.567 回答
9
使用 if 子句?我也很好奇你为什么要忽略这种数学上的不可能性。您确定在这种情况下您的输入没有错误/没有意义吗?
于 2010-04-01T20:26:02.160 回答
1
如果您不介意引入一个小错误,则可以在分母上添加一个小值,假设您正在执行浮点运算。显然定义了一些小值:
DBL_MIN 是最小的双精度
DBL_EPSILON 是最小的 double st x+DBL_EPSILON != x
所以我会尝试
#include <float.h>
#define EPS DBL_MIN
double divModified(double num, double denom) {
return num / (denom + EPS);
}
于 2010-04-02T03:40:08.030 回答
0
IEEE 754(浮点规范)说 0.0/0.0 不是数字,即NaN
. 如果您希望它是其他任何东西,到目前为止,最好的方法是检测子句中的操作数何时都为零if
并返回您宁愿给出的值。或许是这样的:
#define WonkyDiv(a,b) ((a)==0.0&&(b)==0.0 ? 0.0 : (a)/(b))
float wonkyResult = WonkyDiv(numerator, denominator);
于 2010-04-03T22:01:40.083 回答