这种晶圆厂的实施是否适用于NaN?

时间:2017-05-12 13:57:14

标签: c floating-point language-lawyer

我有以下相对简单(虽然不是很有效)的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>

1 个答案:

答案 0 :(得分:2)

关于指定浮点行为的C标准是松散的,除了附件F(可选),并且在不采用附件F的情况下符合C标准的C实现可以按照您的指示行事。

然而,质量实施至少会尝试符合IEEE 754-2008(与C标准附录F中提到的IEC 60559相同)。 IEEE 754-2008在第5.5.1节中说,否定浮点操作数(包括NaN)会改变其符号位。