我有一个包含两个int类型变量的程序。
int num;
int other_num;
/* change the values of num and other_num with conditional increments */
printf ("result = %f\n", (float) num / other_num);
float r = (float) num / other_num;
printf ("result = %f\n", r);
第一个printf中写入的值与第二个printf写入的值不同(以小数点后6位打印时为0.000001)。
在除法之前,值为:
num = 10201
other_num = 2282
我已将结果数字打印到小数点后15位。这些数字在小数点后7位有所不同,这解释了第6位的差异。
以下是15位小数的数字:
4.470201577563540
4.470201492309570
我知道浮点舍入问题,但我期望在赋值和printf参数中执行时计算结果是相同的。
为什么这种期望不正确?
感谢。
答案 0 :(得分:8)
可能是因为FLT_EVAL_METHOD
在你的系统上不是0。
在第一种情况下,表达式(float) num / other_num
具有名义类型float
,但可能以更高的精度进行评估(如果您使用的是x86,可能是long double
)。然后转换为double
以传递给printf
。
在第二种情况下,将结果分配给类型为float
的变量,这会强制丢弃多余的精度。然后,float
在传递给double
后会升级为printf
。
当然没有实际数字,这只是猜测。如果您想要更明确的答案,请提供有关您问题的完整详细信息。
答案 1 :(得分:1)
该点是程序执行期间表达式结果的实际位置。如果编译器决定在特定情况下可以进行这种优化,则C值可以存在于内存(包括高速缓存)上,也可以只存在于寄存器上。
在第一个printf中,表达式结果存储在一个寄存器中,因为该值只是在同一个C指令中使用,所以编译器认为(正确地)将它存储在不太易变的地方是没用的;因此,根据体系结构,该值将存储为double或long double。
在第二种情况下,编译器没有执行这样的优化:值存储在堆栈中的变量中,该变量是内存,而不是寄存器;因此,相同的值在第23位有效位被截断。
更多示例是provided by streflop及其文档。