printf() 是否修改其参数?

Does printf() modify its parameters?

我试图了解不同的语言如何处理浮点数。我知道浮点表示存在一些固有问题,这就是为什么如果你在 Python 中执行 0.3 + 0.6,你会得到 0.899999 而不是 0.9

然而,这些代码片段让我大吃一惊:

double x = 0.1,
    sum = 0;

for(int i=0; i<10; ++i) 
    sum += x;

printf("%.9lf\n",sum);
assert(sum == 1.0);

上面的代码片段工作正常。它打印 1.0。 但是,由于断言失败,以下代码片段会出现运行时错误:

double x = 0.1,
    sum = 0;

for(int i=0; i<10; ++i) 
    sum += x;

assert(sum == 1.0);
printf("%.9lf\n",sum);

以上两个代码段的唯一变化是 assert 和 printf 语句的顺序。这使我认为 printf 正在以某种方式修改其参数并以某种方式四舍五入。

有人可以解释一下吗?

某些处理器(例如 x86)具有比数据类型精度更高的浮点寄存器(80 位,与双精度的 64 位相比)。调用 printf() 会使这些寄存器存储在堆栈中,其中仅为变量分配了 64 位。这会导致您观察到的差异。

有关详细信息,请参阅 What every computer scientist should know about floating-point arithmetic.

printf() 不修改其参数。

我无法想象在遇到错误时寻求帮助却不说明您遇到的错误。你的意思是它断言。您确定两者都不断言,但出于某种原因您只看到在 printf() 之前断言的那个吗?