gpt4 book ai didi

c - 当 x 是 NaN 或 inf 时,为什么 floor, ceil 实现返回 x + x?

转载 作者:行者123 更新时间:2023-12-04 12:08:41 24 4
gpt4 key购买 nike

我正在阅读 IEEE-754 数学函数在 glibc 中的实现。
这是floor执行。

float
__floorf(float x)
{
int32_t i0,j0;
uint32_t i;
GET_FLOAT_WORD(i0,x);
j0 = ((i0>>23)&0xff)-0x7f;
if(j0<23) {
if(j0<0) {
/* return 0*sign(x) if |x|<1 */
if(i0>=0) {i0=0;}
else if((i0&0x7fffffff)!=0)
{ i0=0xbf800000;}
} else {
i = (0x007fffff)>>j0;
if((i0&i)==0) return x; /* x is integral */
if(i0<0) i0 += (0x00800000)>>j0;
i0 &= (~i);
}
} else {
if(__builtin_expect(j0==0x80, 0)) return x+x; /* inf or NaN */
else return x; /* x is integral */
}
SET_FLOAT_WORD(x,i0);
return x;
}

有趣的部分是 if(__builtin_expect(j0==0x80, 0)) return x+x; /* inf or NaN */ .
为什么会返回 x+xx是 inf 还是 NaN?
为什么不直接返回 x ?

编辑

我的代码来自 https://github.com/lattera/glibc/blob/895ef79e04a953cac1493863bcae29ad85657ee1/sysdeps/ieee754/flt-32/s_floorf.c并假设它是 glibc 的 fork。

最佳答案

目的是引发异常。当输入到floor是一个信号 NaN,该例程应该引发浮点无效操作异常。 1 与其调用一些会通过操作浮点状态寄存器中的位来做到这一点的例程,不如简单地计算 x+x 更容易。 ,因为向自身(或任何东西)添加信号 NaN 将引发无效操作异常。
这在数学库例程的实现中很常见。再举一个例子,考虑 sin(x) .对于非常小的值 x , sin(x)就这么近 x那个x是浮点格式可表示的最接近的值,因此返回值应为 x .但确切的数学 sin x 并不完全是 x (如果 x 不为零),因此应该引发不精确的异常。为此,例程可能会返回,例如 x + x*x .当x非常小(但不是零),这将计算为与 x 相同但它会引发无效异常。
请注意在这种情况下的额外好处:当 x为零,x + x*x不会引发不精确的异常。因此,该表达式适用于零和非常小的非零情况。因此,它不仅替代了手动引发异常,还替代了基于是否 x 的分支。是否为零。这在这些表达中并不少见。它们是实现该功能的有效方式。
脚注
1 浮点异常不是 C++ 异常。它们的处理方式取决于浮点环境的设置。最常见的是,它们只是引发程序稍后可以检查的标志。但它们也可能导致改变程序执行的陷阱,如 C++ 异常。

关于c - 当 x 是 NaN 或 inf 时,为什么 floor, ceil 实现返回 x + x?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55508755/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com