我的代码中有一些地方我想确保 2 个任意浮点数(32 位单精度)的除法不会溢出。目标/编译器不保证(足够明确)对 -INF/INF 的良好处理,并且(不完全保证 IEEE 754 的异常值 - (可能未定义) - 并且目标可能会改变)。另外,我无法对这几个特殊位置的输入做出保存假设,并且我绑定到 C90 标准库。
我读过了每个计算机科学家都应该了解的浮点运算知识 http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html但说实话,我有点失落。
所以...我想问社区,下面的代码是否可以解决问题,以及是否有更好/更快/更准确/更正确的方法来做到这一点:
#define SIGN_F(val) ((val >= 0.0f)? 1.0f : -1.0f)
float32_t safedivf(float32_t num, float32_t denum)
{
const float32_t abs_denum = fabs(denum);
if((abs_denum < 1.0f) && ((abs_denum * FLT_MAX) <= (float32_t)fabs(num))
return SIGN_F(denum) * SIGN_F(num) * FLT_MAX;
else
return num / denum;
}
编辑:已更改((abs_denum * FLT_MAX) < (float32_t)fabs(num))
to ((abs_denum * FLT_MAX) <= (float32_t)fabs(num))
正如 Pascal Cuoq 所推荐的那样。
您可以尝试提取 num 和 denum 的指数和尾数,并确保条件:
((exp(num) - exp (denum)) > max_exp) && (mantissa(num) >= mantissa(denum))
并根据输入的符号,生成相应的INF。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)