aka*_*ice 6 c c++ floating-point visual-studio
我对MSVC ldexp行为感到有些惊讶(它发生在Visual Studio 2013中,但也适用于所有旧版本,至少到2003年......).
例如:
#include <math.h>
#include <stdio.h>
int main()
{
double g=ldexp(2.75,-1074);
double e=ldexp(3.0,-1074);
printf("g=%g e=%g \n",g,e);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
版画
g=9.88131e-324 e=1.4822e-323
Run Code Online (Sandbox Code Playgroud)
第一个g是奇怪的圆形...
它是2.75*fmin_denormalized,所以我绝对期望第二个结果e.
如果我评价2.75*ldexp(1.0,-1074)我正确得到与e相同的值.
我的期望是否太高,或者微软是否未能遵守某些标准?
虽然问题没有明确说明这一点,但我认为提问者预期的输出是:
g=1.4822e-323 e=1.4822e-323
Run Code Online (Sandbox Code Playgroud)
这是我们对C/C++编译器的期望,它承诺严格遵守IEEE-754.问题是标签都C和C++我将讨论C99在这里,因为这是我手上的标准.
在附件F中,描述了IEC 60559浮点运算(其中IEC 60559基本上是IEEE-754的另一个名称),该C99标准规定:
定义的实现
__STDC_IEC_559__应符合本附件中的规范.[...]这些scalbn和scalbln功能<math.h>提供了IEC 60559附录中推荐的scalb功能.
在该附件中,F.9.3.6节规定:
在二进制系统上,
ldexp(x, exp)相当于scalbn(x, exp).
该C99标准引用的附录是1985年版IEEE-754的附录,其中我们发现scalb函数定义如下:
Scalb(Y,N)返回y×2 Ñ为积分值对应N不用计算2 Ñ.
scalb定义为乘以2的幂,乘法必须根据标准根据当前的舍入模式正确舍入.因此,如果编译器定义,则符合标准的C99编译器ldexp()必须返回正确舍入的结果.在没有库调用设置舍入模式的情况下,默认舍入模式"舍入到最接近或甚至"是有效的.__STDC_IEC_559__
我无法访问MSVC 2013,因此我不知道它是否定义了该符号.这甚至可能取决于编译器标志设置,例如/fp:strict.
在追踪我的C++ 11标准副本之后,我找不到任何__STDC_IEC_559__关于IEEE-754绑定的参考或任何语言.根据这个问题的答案,这是因为参考C99标准包含了这种支持.
| 归档时间: |
|
| 查看次数: |
261 次 |
| 最近记录: |