我有以下相对简单(虽然不是很有效)的fabs函数的实现:
double fabs(double x) {
if (x == 0.0) return 0.0; // deals with both 0.0 and -0.0.
if (x > 0.0) return x; // deals with ]0.0 .. +inf], but "(NaN > 0.0)" is false
return -x; // deals with [-inf .. 0.0[, and NaNs
}我在这个实现中发现的唯一“棘手问题”是,给定一个正的NaN,它会返回一个负值。然而,我在标准中找不到任何东西说这是不允许的。
特别是,我发现:
第7.12.7节:
描述 函数计算浮点数x的绝对值。 返回 晶圆厂的函数返回x_x。
这并不会对非数字的事物施加任何限制,即非数字。
F.10.4.2:
蚕场功能 - fabs(±0)返回+0。 -蚕豆(±∞)返回+∞。 返回的值是精确的,并且与当前的舍入方向模式无关。
再说一次,对NaNs没有任何限制。
F.10,项目11:
带有NaN参数的函数返回一个NaN结果,并且不引发浮点异常,除非另有说明。
没有对签名的限制。
特别是,我没有提到signbit(fabs(x))应该为任何浮点x返回0,这就是我的实现所违背的。
但是,Ignorantia juris是没有理由的,因此我想确定这个实现是一致的。我找到的libc实现(glibc,musl)使用各种低级别的位技巧或编译器内置来提高效率,这一点也没有帮助,因此在这种情况下没有提供太多的信息。
为了澄清,我添加了language-lawyer标记,因为我更感兴趣的是标准本身需要什么,而不是编译器自己做什么,尽管如果他们以“意外”的方式做一些事情(例如,MSVC似乎保留了@ -nan的负号),这可以证实标准并不那么严格(但同样地,MSVC不是标准的一个很好的例子--无论如何.)。
发布于 2017-05-14 13:48:23
除了附件F(这是可选的)之外,C标准在指定浮点行为方面是松懈的,而不采用附件F的符合C标准的C实现可能会像您所指出的那样运行。
然而,高质量的实现至少将试图符合IEEE754-2008(这与C标准附件F中提到的IEC 60559相同)。IEEE754-2008在第5.5.1条中说,否定浮点操作数(包括NaN)会改变其符号位。
https://stackoverflow.com/questions/43939568
复制相似问题