[英]Retaining maximum possible accuracy on float interpolation
我們知道點X1和X2有各自的點Y1和Y2,所以我們可以用任意X計算Y:
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;
對於整數數學公式A,只要乘法(X - X1) * (Y2 - Y1)
結果保持在類型的范圍內,表現就更好。 公式B不起作用,因為如果X1 <= X <= X2
,則除法總是等於0
。
對於浮點,兩者都應該有效,但我認為B會提供更好的准確性,因為乘法結果會更小。
我對浮點精度的假設是否正確?
是否有一些我沒有考慮的浮點怪癖?
假設IEEE 754浮點表示。
注1:我對浮點情況感興趣,整數數學非常簡單。
注2:FP公式的變量可能具有非整數值,但NaN和Infs不在問題范圍內。
為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個符號不同的相似數字)。 代碼可以通過反轉point1和point2的角色來選擇X1,Y1
或X2,Y2
作為偏移量。 選擇最接近X,Y的偏移將提高准確性 。
使用FP數學, *
和/
強調FP編號允許的指數范圍:產品的精度可以預期在數學上正確的答案范圍內,但范圍可能會溢出。
+
和-
強調精度:范圍很少是一個問題,但在用於形成總和的有效數字中可能存在大的取消。
如果所有坐標值最初都是整數,建議使用2x寬整數數學並得出最佳答案。
如果最終結果是整數化的,則保險代碼使用iy = (int) round(Y);
假設沒有發生下溢或溢出,它們在精度方面應該大致相同:乘法和除法都會產生相同的相對誤差,並且由於誤差大致是乘法的,因此執行運算的順序不會有太大差別。
如果你對所涉及的術語的相對大小有所了解,你可能能夠重新排列術語,使得減法是精確的,這可能會略微減少誤差。
通常,乘法和除法很少會導致精度的顯着降低。 因為這些是浮點數 ,具有用於比例和有效數字的單獨字段,所以獲得大的中間結果本身不是問題。 2e100/3e100
和2/3
(所有意圖和目的)同樣准確。
另一方面,加法或減法的結果比操作數小得多,這是導致精度損失的常見原因。
考慮到這一點,這兩種形式基本相同。 如果您的數字是“主流”(即乘法不會導致上溢/下溢),那么您不會遇到任何形式的任何問題。 如果你不能認為你的數字是主流,那么你必須采取各種特殊預防措施才能獲得好結果。
現在,我建議在(A)和(C)之間選擇,而不是考慮兩種形式(A)和(B):
Y = (X - X1) * (Y2 - Y1) / (X2 - X1) + Y1; (A)
Y = (X - X2) * (Y2 - Y1) / (X2 - X1) + Y2; (C)
並選擇第一個因子X - X1
或X - 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
所以,你的問題的快速答案是:
中間結果的大小本身並不重要。 優先考慮(B)而不是(A)。
始終認為加法和減法更可能是精度損失的原因。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.