下面的C程序在我的Mac和Linux上产生了不同的结果。 我很惊讶,因为我认为
在Mac上的输出是:
libm
的实现在某种程度上是标准化的。#include<math.h>
#include<stdio.h>
int main()
{
double x18=-6.899495205106946e+01;
double x19 = exp(-x18);
printf("x19 = %.15e\n", x19);
printf("x19 hex = %llx\n", *((unsigned long long *)(&x19)));
}
在Mac上的输出是:
x19 = 9.207186811339878e+29
x19 hex = 46273e0149095886
还有在Linux平台上
x19 = 9.207186811339876e+29
x19 hex = 46273e0149095885
以下两个都是没有任何优化标志编译的:
gcc -lm ....
我知道不应该将浮点数进行严格的比较。
在调试过程中,这个问题出现了。遗憾的是,使用这个计算的算法证明是数值不稳定的,而这种微小的差异会导致最终结果的显著偏差。但这是一个不同的问题。
我只是惊讶于像exp
这样的基本操作没有像IEEE 754规定的基本代数运算那样标准化。
对于不同机器或不同版本的libm
实现,我可以依赖哪些精度假设?
由于下面的讨论,我使用mpmath
以高于机器精度的方式计算值,并且我得到了两个更多数字的结果9.2071868113398768244
,因此对于我的两个结果,最后一位已经是错误的。Linux上的结果可以通过向下舍入此值来解释,如果计算机使用向上舍入,则Mac上的结果也会出错。
%a
。 - rocksportrocker