2015-01-12 69 views
4

最大可能的準確度我們知道,點X1和X2各點Y1和Y2,所以我們可以計算Y表示任何X:保留在浮動插值

X - X1 Y - Y1 
------- = ------- 
X2 - X1 Y2 - Y1 

我們可以得到一個簡單的公式(A)出的是:

Y = (X - X1) * (Y2 - Y1)/(X2 - X1) + Y1; 

這應該是數學上等效(B):

Y = (X - X1)/(X2 - X1) * (Y2 - Y1) + Y1; 

對於整數數學形式只要乘積(X - X1) * (Y2 - Y1)結果與類型的範圍保持一致,則ula A表現更好。公式B將不起作用,因爲如果X1 <= X <= X2,那麼除法總是等於0

對於浮點這兩個都應該工作,但我認爲B會提供更好的精度,因爲乘法結果將保持較小。

  1. 我對浮點精度的假設是否正確?

  2. 有沒有我不考慮的浮點偏差?

假設IEEE 754浮點表示法。注意1:我對浮點型情況感興趣,整型數學非常直截了當。

注2:FP公式中的變量可能有非整數值,但NaN和Infs不在問題範圍內。

+0

請註明:您對具有浮點值或僅具有整數值的點感興趣嗎? – chux

回答

1

一般而言,乘法和除法很少引起的精度的顯著損失。因爲這些數字是浮點數,對於比例和有效數字有單獨的字段,所以獲得大的中間結果本身不是問題。 2e100/3e1002/3(對於所有意圖和目的)同樣準確。

另一方面,增加或減少的結果幅度遠小於操作數,這是導致精度損失的更常見的原因。

考慮到這一點,這兩種形式基本上是等價的。如果你的數字是「主流」(即乘法不會導致超/下溢),那麼你將不會遇到任何形式的問題。如果你不能認爲你的數字是主流,那麼你必須採取各種特殊的預防措施才能獲得好的結果。

現在,而不是考慮兩種形式(A)和(B),我建議之間(A)選擇和(C):

Y = (X - X1) * (Y2 - Y1)/(X2 - X1) + Y1; (A) 
Y = (X - X2) * (Y2 - Y1)/(X2 - X1) + Y2; (C) 

和選擇形式,其中第一因子X - X1X - X2幅度較小。這樣,如果Y結果很小,則可以將精度損失降至最低。

例如,讓我們使用

(X1,Y1) = (-100, -100) 
(X2,Y2) = (0, 0) 
X = 0.76 

與精度三位數。然後,我們得到(A):

Y = (0.76 - -100) * (0 - -100)/(0 - -100) + -100 
    = 101 * 100/100 - 100 
    = 1 

而(C),我們得到:

Y = (0.76 - 0) * (0 - -100)/(0 - -100) + 0 
    = 0.76 * 100/100 + 0 
    = 0.76 

所以,快速回答你的問題是:

  1. 的大小中間結果本身並不重要。 (B)不是(A)的理由。

  2. 始終認爲加法和減法更可能是精度損失的根源。

2

假設沒有下溢或溢出發生,它們在精度上應該大致相當:乘法和除法都會產生相同的相對誤差,並且由於誤差大致相乘,您執行操作的順序將贏得'沒有什麼不同。

如果您對涉及的術語的相對量值有所瞭解,則可以重新排列術語,使得減法是準確的,這可能會稍微減少誤差。

+0

你是說乘法/除法永遠不會成問題,但加法/減法會怎麼樣? (當然,不包括任何溢出情況) – user694733

+0

不僅如此,在某些情況下,可以精確地進行減法,例如,請參閱http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html中的定理11 –

+0

還要小心最後的添加:在某些情況下,您可能會遇到災難性的取消。 –

3

爲了解決以下爲Y

X - X1 Y - Y1 
------- = ------- 
X2 - X1 Y2 - Y1 

兩者(A)和(B)的行爲相似:

(A) Y = (X - offsetX) * deltaY/deltaX + offsetY; 
(B) Y = (X - offsetX)/deltaX * deltaY + offsetY; 

如果點原本是整數,「B ...乘法結果將保持較小。「可能成立,但其他方面|deltaX||deltaY|可能都小於1,然後這種假設可能會失敗。

要提高準確度,請考慮減去2個數字(或添加2個符號不同的相似數字)的效果。代碼可以選擇X1,Y1X2,Y2作爲抵消,通過顛倒point1和point2的角色。 選擇最接近X的偏移量,Y將提高精度

使用FP數學,*/強調FP編號允許的指數範圍:產品的精度可以預期在數學上正確答案的某個位內,但範圍可能會溢出。

+ and -強調精度:範圍很少成問題,但可能會在用於形成總和的有效數中有很大的取消。


如果所有的座標值最初都是整數,建議使用2x寬整數運算並得出最佳答案。

如果最後的結果是爲整數化的,確保代碼使用iy = (int) round(Y);