浮点算术使用到最近

时间:2014-05-28 15:03:55

标签: c floating-point floating-accuracy floating-point-precision

关于C中的库fenv.h,我很难理解使用fesetround()和FE_TONEAREST(默认)方向时舍入方向模式的作用。

图书馆有四种类型的舍入方向:

  • FE_TONEAREST
  • FE_UPWARD
  • FE_DOWNWARD
  • FE_TOWARDZERO

双打:

double res = 0.14*50;
printf ("res = %.50lf \n",res);

返回:res = 7.00000000000000088817841970012523233890533447265625 (编译器说res> 7)

然而,在花车上:

float res = 0.14*50;
printf ("res = %.50f \n",res);

返回7.00000000000000000000000000000000000000000000000000(res = 7)

长双打:

long double a;
long double b;
scanf("%Lf",&a);
scanf("%Lf",&b);
long double res = a*b;
printf("%.50Lf \n",res);

返回7.00000000000000000000000000000000000000000000000000(res = 7)

对于FE_TONEAREST模式的浮点算术,double类型是否更具风险?

1 个答案:

答案 0 :(得分:4)

您的问题与舍入到最近的舍入模式无关,这是默认模式。您的问题的答案是0.14f0.14不同0.14L ,并且它们都不等于14/100 的数学比率。当乘以50时,这些(不同的)数字0.14f0.140.14L的行为会有所不同。

舍入模式会影响乘法的行为,而不会影响0.14f0.140.14L(*)的值。 0.14 * 50 > 70.14的价值相关的原因与*的行为相关。因此,不要假设单独执行*的舍入模式会解释您所看到的内容。

  

对于FE_TONEAREST模式的浮点算术,double类型是否更具风险?

不,绝对没有。


请注意,float实验应为float res = 0.14f*50;才能有意义。否则,您将乘以双精度常量0.14,然后将结果舍入为float。这个操作产生数学结果比通过乘以单精度十进制常数更常见是正常的,但这又与舍入模式无关,而与乘法的实际操作数有关。


(*)C99 6.4.4.2:5浮动常数转换为内部格式,就像在翻译时一样。