roc*_*ker 8 c linux precision macos numeric
以下C程序在我的Mac和Linux上产生不同的结果.我很惊讶,因为我认为实施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)));
}
Run Code Online (Sandbox Code Playgroud)
Mac上的输出是
x19 = 9.207186811339878e+29
x19 hex = 46273e0149095886
Run Code Online (Sandbox Code Playgroud)
在Linux上
x19 = 9.207186811339876e+29
x19 hex = 46273e0149095885
Run Code Online (Sandbox Code Playgroud)
两者都编译时没有任何优化标志,如下所示:
gcc -lm ....
Run Code Online (Sandbox Code Playgroud)
我知道我永远不应该比较漂浮物.
在调试期间出现了这个问题,遗憾的是使用这种计算证明的算法在数值上不稳定,这种微小的差异导致最终结果的显着偏差.但这是一个不同的问题.
令我感到惊讶的是,这些基本操作exp
并未标准化,因为我可以期待IEEE 754规定的基本代数运算.
libm
对于不同机器或不同版本的不同实现,是否有任何关于精度的假设?
由于下面的讨论我曾经mpmath
计算过高于机器精度的值,我得到两个数字的结果9.2071868113398768244
,所以对于我的两个结果,最后一个数字已经错了.linux上的结果可以通过向下舍入此值来解释,如果计算机使用四舍五入,则Mac结果也会关闭.
C99 规范指出(其他版本应该类似):
\n\n\n\n\nJ.3 实现定义的行为
\n\n1 需要一个一致的实现来记录其在本节列出的每个领域中的行为选择。以下是实现定义的:
\n\n...
\n\nJ.3.6 浮点
\n\n\xe2\x80\x94 中的浮点运算以及返回浮点结果的库函数的精度
\n<math.h>
(<complex.h>
5.2.4.2.2)。
这意味着 GNU libm 和 BSD libm 可以自由地具有不同级别的精度。\n可能发生的情况是,OSX 上的 BSD 实现舍入到最近的(最后一个单位)ULP,而 GNU 实现则截断到下一个 ULP。
\n