1

我有一个带有两个 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 中写入的值不同(相差 0.000001,当以 6 个小数位打印时)。

在除法之前,值是:

num = 10201 
other_num = 2282

我已将结果数字打印到小数点后 15 位。这些数字在小数点后第 7 位不同,这解释了第 6 位的差异。

以下是小数点后 15 位的数字:

4.470201577563540
4.470201492309570

我知道浮点舍入问题,但我希望在赋值和 printf 参数中执行时计算结果相同。

为什么这个期望不正确?

谢谢。

4

2 回答 2

8

可能是因为FLT_EVAL_METHOD您的系统上不是 0。

在第一种情况下,表达式(float) num / other_num具有标称类型float,但可能会以更高的精度进行评估(如果您使用的是 x86,则可能long double)。然后将其转换double为传递给printf.

在第二种情况下,您将结果分配给 type 的变量float,这会强制删除多余的精度。然后在传递给 时float提升到。doubleprintf

当然,如果没有实际数字,这一切都只是猜测。如果您想要更明确的答案,请提供有关您的问题的完整详细信息。

于 2013-05-17T22:19:51.113 回答
1

该点是程序执行期间表达式结果的实际位置。如果编译器认为这种优化在特定情况下是可能的,C 值可以存在于内存(包括缓存)或仅存在于寄存器上。

在第一个 printf 中,表达式结果存储在寄存器中,因为该值仅在同一 C 指令中使用,因此编译器(正确地)认为将其存储在易失性较小的地方是没有用的;结果,根据体系结构,该值存储为双精度或长双精度。

第二种情况,编译器没有进行这样的优化:值是存放在栈内的一个变量中,是内存,不是寄存器;因此,相同的值在第 23 个有效位被截断。

streflop及其文档提供了更多示例。

于 2013-05-17T22:45:19.633 回答