赋值和printf之间的舍入不同
我有一个程序有两个int类型的变量。
int num;
int other_num;
/* change the values of num and other_num with conditional increments */
printf ("result = %fn", (float) num / other_num);
float r = (float) num / other_num;
printf ("result = %fn", r);
在第一个printf中写入的值与由第二个printf写入的值不同(当以小数点后6位打印时,为0.000001)。
在划分之前,这些值是:
num = 10201
other_num = 2282
我将结果数字打印到小数点后15位。 这些数字在第七个小数位差异,这解释了第六位数的差异。
这里是有15位小数的数字:
4.470201577563540
4.470201492309570
我知道浮点四舍五入问题,但我期望计算结果在赋值和printf参数中执行时是相同的。
为什么这个期望不正确?
谢谢。
可能是因为FLT_EVAL_METHOD
在系统上不是0。
在第一种情况下,表达式(float) num / other_num
具有名义类型float
,但可能以更高的精度评估(如果您使用的是x86,可能是long double
)。 然后它被转换为double
来传递给printf
。
在第二种情况下,将结果赋值给float
类型的变量,这会强制降低过多的精度。 当传递给printf
时, float
会被提升为double
。
当然,没有实际的数字,这只是猜测。 如果您想要更明确的答案,请提供有关问题的完整详细信息。
重点是程序执行过程中表达式结果的实际位置。 如果编译器决定在特定情况下可以进行这种优化,那么C值可以存储在内存(包括缓存)上,也可以只存在于寄存器上。
在第一个printf中,表达式结果存储在一个寄存器中,因为该值只用于相同的C指令中,所以编译器认为(正确),将其存储在某个不太易变的地方是没有用的; 作为结果,根据体系结构的不同,该值将以双精度或长精度双精度来存储。
在第二种情况下,编译器没有执行这种优化:该值存储在堆栈中的一个变量中,即内存,而不是寄存器; 因此相同的值因此在第23个有效位处被切断。
更多示例由streflop及其文档提供。
链接地址: http://www.djcxy.com/p/90301.html