我有以下相对简单(虽然不是很有效)的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:
描述
fabs函数计算浮点数x的绝对值。
返回
fabs函数返回| x |。
这不会对不是数字的东西施加任何限制,即NaN。
F.10.4.2:
晶圆厂的功能
- fabs(±0)返回+0。
- fabs(±∞)返回+∞。
返回的值是精确的,与当前的舍入方向模式无关。
同样,对NaN没有限制。
F.10,第11项:
具有NaN参数的函数返回NaN结果并且不引发浮点异常,除非另有说明。
对签名没有限制。
特别是,我没有提到signbit(fabs(x))
应该为任何浮点x
返回0的事实,这实际上是我的实现违反的。
然而, Ignorantia juris non excusat ,因此我想确定这个实现符合要求。我发现的libc实现(glibc,musl)使用各种低级别的技巧或编译器内置函数是有效的,因此在这种情况下不提供太多信息。
为了澄清,我添加了language-lawyer
标签,因为我对标准本身需要的内容比对编译器本身所做的更感兴趣,尽管他们以“意外”的方式做事(例如MSVC似乎为了保持@WeatherVane报告的-nan
的减号,这可以确认标准不是那么严格(但话说再说一遍,MSVC不是标准一致性的好例子......)。 / p>
答案 0 :(得分:2)
关于指定浮点行为的C标准是松散的,除了附件F(可选),并且在不采用附件F的情况下符合C标准的C实现可以按照您的指示行事。
然而,质量实施至少会尝试符合IEEE 754-2008(与C标准附录F中提到的IEC 60559相同)。 IEEE 754-2008在第5.5.1节中说,否定浮点操作数(包括NaN)会改变其符号位。