C中的浮点舍入

Cal*_*all 2 c floating-accuracy

我用浮动遇到了一些奇怪的舍入行为.下面的代码演示了这个问题.解决这个问题的最佳方法是什么?我一直在寻找解决方案,但没有太多运气.

#include<stdio.h>

int main(void)
{   
    float t;
    t = 5592411;
    printf("%f\n", 1.5*t);
    t *= 1.5;
    printf("%f\n", t);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

上面的代码应打印出相同的值,但我在使用GCC 4.7.2进行设置时得到了这个值:

8388616.500000

8388616.000000

如果我使用计算器,我得到第一个值,所以我假设第二个值是以某种方式舍入.我有相同的Fortran代码,它不会对值进行舍入(具有0.5).

Tom*_*mmy 8

1.5是一个double常数而不是一个float和C有自动推广规则.所以,当你执行1.5*t所发生的事情是(i)t转换为a double; (ii)double乘以double 1.5; (iii)double打印(如%fa的格式化程序double).

相反,t *= 1.5提升t为double,执行双乘,然后截断结果以将其存储回[单精度] float.

有关证据,请尝试:

float t;
t = 5592411;
printf("%f\n", 1.5f*t); // multiply a float by a float, for no promotion
t *= 1.5;
printf("%f\n", t);
return 0;
Run Code Online (Sandbox Code Playgroud)

要么:

double t; // store our intermediate results in a double
t = 5592411;
printf("%f\n", 1.5f*t);
t *= 1.5;
printf("%f\n", t);
return 0;
Run Code Online (Sandbox Code Playgroud)

  • 单精度浮点数的一般规则是六到九位有效十进制数字,因此'8388616'的七位数字在预期范围内.更具体一点,我在分数中计算了20个二进制数字(在隐含的前导1之后),IEEE 754允许23; 8388616.5你需要24.因此IEEE标准浮点数不够准确. (2认同)