簡體   English   中英

與Mac和Linux上的exp函數略有不同的結果

[英]Slightly different result from exp function on Mac and Linux

以下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)));
}

在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結果也將關閉。

C99規范指出(其他版本應該相似):

J.3實現定義的行為

1需要一個一致的實現來記錄其在本子節中列出的每個區域中的行為選擇。 以下是實現定義的內容:

...

J.3.6浮點數

—浮點運算和<math.h><complex.h>中返回浮點結果的庫函數的准確性(5.2.4.2.2)。

意味着GNU libm和BSD libm可以自由地具有不同級別的准確性。 可能發生的情況是,OSX上的BSD實現四舍五入到最近的ULP(最后一個單元),而GNU實現截短到下一個ULP。

IEEE-754行為是在二進制級別上指定的。 使用Linux,我獲得了Python的本地mathmpmath和MPFR相同的值(通過gmpy2 )。 但是,在三種方法之間,轉換為十進制會有所不同。

>>> import mpmath, gmpy2
>>> import mpmath, gmpy2, math
>>> x18=68.99495205106946
>>> x19=math.exp(x18)
>>> mp18=mpmath.mpf("68.99495205106946")
>>> mp19=mpmath.exp(mp18)
>>> gp18=gmpy2.mpfr("68.99495205106946")
>>> gp19=gmpy2.exp(gp18)
>>> x18 == mp18
True
>>> x18 == gp18
True
>>> x19 == mp19
True
>>> x19 == gp19
True
>>> print(x18, mp18, gp18)
68.99495205106946 68.9949520510695 68.994952051069461
>>> print(x19, mp19, gp19)
9.207186811339876e+29 9.20718681133988e+29 9.2071868113398761e+29

轉換為Python的任意精度整數形式后,所有三個結果也顯示為精確。

>>> hex(int(x19))
'0xb9f00a484ac42800000000000'
>>> hex(int(mp19))
'0xb9f00a484ac42800000000000'
>>> hex(int(gp19))
'0xb9f00a484ac42800000000000'

因此(至少一個)Linux數學庫mpmathgmpy2.mpfr同意。

免責聲明:我維護gmpy2並在過去為mpmath做出了貢獻。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM