c – 标准对于std :: pow,std :: log等cmath函数有什么看法?

前端之家收集整理的这篇文章主要介绍了c – 标准对于std :: pow,std :: log等cmath函数有什么看法?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
标准是否保证函数在所有实现中返回完全相同的结果?

例如,用于32位IEEE浮点数的pow(浮点数,浮点数).如果传入相同的两个浮点数,则所有实现的结果是否相同?

或者是否有一些灵活性,标准允许根据用于实施战俘的算法的微小差异?

解决方法

不,C标准不要求cmath函数的结果在所有实现中都是相同的.对于初学者,您可能无法获得IEEE-754 / IEC 60559浮点运算.

也就是说,如果一个实现使用IEC 60559并定义__STDC_IEC_559__,那么它必须遵守C标准的附录F(是的,你的问题是关于C,但是C标准遵循C标准的C标准,如math.h ).附件F规定:

  • The float type matches the IEC 60559 single format.
  • The double type matches the IEC 60559 double format.
  • The long double type matches an IEC 60559 extended format,else a
    non-IEC 60559 extended format,else the IEC 60559 double format.

此外,它说正常算术必须遵循IEC 60559标准:

  • The +,,*,and / operators provide the IEC 60559 add,subtract,multiply,and divide operations.

它还要求sqrt遵循IEC 60559:

  • The sqrt functions in <math.h> provide the IEC 60559 square root operation.

然后继续描述其他几个浮点函数的行为,其中大多数你可能对这个问题不感兴趣.

最后,它到达math.h标题,并指定各种数学函数(即sin,cos,atan2,exp等)应如何处理特殊情况(即asin(±0)返回±0,atanh(x)返回NaN并引发| x |> 1等的“无效”浮点异常.但它从来没有确定正常输入的精确计算,这意味着你不能依赖于产生完全相同计算的所有实现.

所以不,它不要求这些函数在所有实现中表现相同,即使这些实现都定义了__STDC_IEC_559__.

这都是从理论的角度来看的.在实践中,情况更糟. cpu通常实现IEC 60559算法,但是可以有不同的舍入模式(因此计算机的结果会有所不同),编译器(取决于优化标志)可能会做出一些不严格符合标准的假设.浮点运算.

所以在实践中,它甚至比理论上更严格,你很可能会看到两台计算机在某些时候产生的结果略有不同.

一个真实世界的例子是glibc,即GNU C库实现. They have a table of known error limits for their math functions跨越不同的cpu.如果所有C数学函数都是位精确的,那些表将显示0个错误的ULP.但他们没有.表格显示其C数学函数确实存在不同的误差量.我认为这句话是最有趣的总结:

Except for certain functions such as sqrt,fma and rint whose results are fully specified by reference to corresponding IEEE 754 floating-point operations,and conversions between strings and floating point,the GNU C Library does not aim for correctly rounded results for functions in the math library[…]

glibc中唯一具有精确位置的东西是C标准的附件F要求精确的东西.正如你在他们的表中所看到的,大多数事情都没有.

猜你在找的C&C++相关文章