Ahm*_*man 4 c floating-point precision numbers
我完全理解与浮点相关的问题,但我看到了一个我无法解释的非常有趣的行为.
float x = 1028.25478;
long int y = 102825478;
float z = y/(float)100000.0;
printf("x = %f ", x);
printf("z = %f",z);
Run Code Online (Sandbox Code Playgroud)
输出是:
x = 1028.254761 z = 1028.254780
现在,如果浮动数字在我将其分配给变量x时未能表示该特定随机值(1028.25478).为什么变量z的情况不一样?
PS我正在使用pellesC IDE来测试代码(C11编译器).
我很确定这里发生的是后一个浮点变量被省略,而是保存在双精度寄存器中; 然后作为参数传递给printf.然后编译器会认为在默认参数提升后以双精度传递此数字是安全的.
我设法使用GCC 7.2.0 生成类似的结果,使用这些开关:
-Wall -Werror -ffast-math -m32 -funsafe-math-optimizations -fexcess-precision=fast -O3
Run Code Online (Sandbox Code Playgroud)
输出是
x = 1028.254761 z = 1028.254800
Run Code Online (Sandbox Code Playgroud)
那个数字略有不同^.
将用于描述-fexcess-precision=fast说:
-fexcess-precision=style此选项允许进一步控制浮点运算发生的机器上的过度精度,其格式的精度或范围比IEEE标准更高,并且交换浮点类型.默认情况下,
-fexcess-precision=fast有效; 这意味着操作可以以比源中指定的类型更宽的精度执行,如果这将导致更快的代码,并且当舍入到源代码中指定的类型时,它是不可预测的.编译C时,如果-fexcess-precision=standard指定了if ,则多余的精度遵循ISO C99中规定的规则; 特别是,强制转换和赋值都会使值四舍五入到它们的语义类型(而-ffloat-store只影响赋值).-fexcess-precision=standard如果使用严格的一致性选项,-std=c99则默认情况下为C启用此选项[ ] . 默认情况下-ffast-math启用-fexcess-precision=fast,无论是否使用严格的一致性选项.
此行为不符合C11