2012-09-09 37 views
2

cmath中exp()函數的浮點實現等價於一個非常高階的截斷泰勒級數展開式嗎?我們應該記住的錯誤的一個可能的來源是用於表示答案的位數的有限性exp()函數的浮點實現是否等價於截斷泰勒級數展開式?

+6

這是極不可能的。硬件算術單元(也用於軟件實現)有更好的「實用」算法,可以更快地收斂。它們通常很模糊,非常漂亮,在純粹的數學家中並不廣爲人知。 –

+0

雖然泰勒級數理論上工作,但系列擴展可能會出現嚴重的精度損失 – 2012-09-09 18:53:41

回答

0

這取決於您正在使用哪個C庫實現。在流行的glibc中,事實並非如此。

+0

我正在使用英特爾編譯器。 glibc使用什麼算法來計算exp()? – Tarek

+1

@Tarek我不知道它到底是什麼,有些東西涉及魔法常量,但爲什麼不自己看呢? – 2012-09-09 17:03:30

+0

@Tarek:我也不知道,但是比泰勒擴展更好的方法是使用[Hermite](http://en.wikipedia.org/wiki/Hermite_interpolation)在有限的時間間隔內使用預先計算的常量並利用爲了將問題簡化爲有限區間,使用浮點的指數格式。 – ybungalobill

1

它取決於編譯器,C運行時和處理器的實現。但是,計算指數的人不太可能使用泰勒展開,因爲存在更好的方法。

按照glibc的,它可以使用它自己的實現,其表示,這在註釋(從sysdeps/IEEE754/DBL-64/e_exp.c):

/* An ultimate exp routine. Given an IEEE double machine number x   */ 
/* it computes the correctly rounded (to nearest) value of e^x    */ 

或者它可以使用硬件支持的處理器指令用於浮點計算,與x86 FPU一樣。在這兩種情況下,您都可能獲得完全精確的正確舍入值。

5

cmath中的exp()函數的浮點執行是否等價於一個非常高階的截斷泰勒級數展開?

相當於?是。這是因爲exp()的任何體面的實施都有一半ULP(最低精度單位)左右的錯誤。忽略有限精度算術的問題,我們總是可以構造一個相同的截斷泰勒級數。

然而,exp()沒有體面的實施將使用泰勒展開。這將非常緩慢,並且不會達到所需的準確度。這將是一個愚蠢的實施。更好的方法是使用這樣一個事實,即在給定浮點數的2個表示的幾乎通用冪的情況下,計算相當容易,因此存在2 x和e x之間的強關係。

1

只是一個例子,你如何可以計算EXP(X):

如果x是相當大的,那麼結果爲+ INF。如果x很小,那麼結果爲0.

設k = round(x/ln 2)。那麼exp(x)= 2^k * exp(x-k ln 2)。 2^k很容易計算。一個小問題是計算x - k ln 2而沒有任何舍入誤差。這很容易:讓L1 = ln 2舍入爲35比特,並且L2 = ln 2 -L1。 k是小整數,所以k * L1沒有舍入誤差,也沒有x - k * L1;那麼我們減去小的k * L2,因此幾乎沒有舍入誤差。我們計算k = round(x *(1/ln 2))。爲了更快地做到這一點(沒有除法),我們計算k = round(x *(1/ln 2))。並且我們檢查x是否接近於零,因此不需要整個計算。無論如何,我們現在計算exp(x),其結果在sqrt(1/2)和sqrt(2)之間。

您可以使用泰勒多項式計算exp(x)。相反,你可能會用一個Chebychev多項式來最小化截止誤差的程度。小心一點,你可以找到一個截止誤差大大低於結果最低位的多項式。

+0

這招讓我想起http://t-a-w.blogspot.de/2006/06/docking-assembly.html – Quonux