簡體   English   中英

在處理浮點值時,我應該結合乘法和除法步驟嗎?

[英]Should I combine multiplication and division steps when working with floating point values?

我知道浮點數和雙打的精度問題,這就是為什么我這樣問:

如果我有一個公式,如: (a/PI)*180.0 (其中PI是常數)

我應該結合除法和乘法,所以我只能使用一個除法: a/0.017453292519943295769236 ,以避免精度損失?

當計算結果的步驟較少時,這是否會使其更精確?

簡短的回答

是的,通常應該將盡可能多的乘法和除法組合成一個操作。 它(通常(*))同時更快,更准確。

π和π/ 180及其反轉都不能完全表示為浮點。 因此,計算將涉及至少一個近似常數(除了所涉及的每個操作的近似值之外)。

因為兩個操作分別引入一個近似,所以可以期望在一個操作中進行整個計算更准確。

在手頭的情況下,分裂或乘法更好嗎?

除此之外,“幸運”的問題是,π/ 180在浮點格式中表示的相對精度是好於還是差於180 /π。

我的編譯器提供了long double類型的附加精度,所以我可以使用它作為參考來回答double這個問題:

~ $ cat t.c
#define PIL 3.141592653589793238462643383279502884197L

#include <stdio.h>

int main() {

  long double heop = 180.L / PIL;
  long double pohe = PIL / 180.L;
  printf("relative acc. of π/180: %Le\n", (pohe - (double) pohe) / pohe);
  printf("relative acc. of 180/π: %Le\n", (heop - (double) heop) / heop);
}
~ $ gcc t.c && ./a.out 
relative acc. of π/180: 1.688893e-17
relative acc. of 180/π: -3.469703e-17

在通常的編程實踐中,人們不會打擾並簡單地乘以180 /π的(浮點表示),因為乘法比除法快得多。 事實證明,在binary64浮點類型double幾乎總是映射到的情況下,π/ 180可以用比180 /π更好的相對精度來表示,所以π/ 180是用來優化精度的常數: a / ((double) (π / 180)) 使用這個公式,總相對誤差大約是常數的相對誤差(1.688893e-17)和除法的相對誤差之和(取決於a的值,但絕不會超過2) - 53 )。

替代方法可獲得更快,更准確的結果

需要注意的是分工是如此昂貴,你可以得到一個更准確的結果通過使用一個乘法和一個FMA更快:讓heop1是最好的double 180 /π近似,並且heop2最好的double 180 /π逼近- heop1 然后,結果的最佳值可以計算為:

double r = fma(a, heop1, a * heop2);

事實上,上述是對實數計算的絕對最佳可能的double近似是一個定理(事實上,它是一個例外的定理。細節可以在“浮點運算手冊”中找到)。 但是,即使為了得到double結果而想要乘以double精度的實常數是該定理的例外之一,上述計算仍然非常准確,並且僅與一些特殊值的最佳double近似不同a


如果像我的一樣,你的編譯器為long double提供了比double更高的精度,你也可以使用一個long double乘法:

// this is more accurate than double division:
double r = (double)((long double) a * 57.295779513082320876798L)

這不是基於FMA解決好,但它是不夠好,對於大多數值a ,它產生最佳的double逼近實際計算。

一般性聲明的反例,即操作應分組為一個

(*)對於大多數常數而言,對組常數更好的說法在統計上是正確的。

如果你碰巧要乘a ,比方說,真正的恆0.0000001 * DBL_MIN ,你會好起來的第一乘以0.0000001 ,然后通過DBL_MIN ,而最終的結果(可以是一個標准化的數字,如果a是超過100萬大或者等等)比你乘以0.0000001 * DBL_MIN的最佳double表示更准確。 這是因為將0.0000001 * DBL_MIN表示為單個double精度值時的相對精度遠低於表示0.0000001的精度。

暫無
暫無

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

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