赋值和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

上一篇: Different rounding between assignment and printf

下一篇: Printing int as float in C