2013-03-16 108 views
0

我有一項任務是儘可能使下列函數精確(速度不是目標)。我必須使用浮法方法中間矩形。你能提出一些建議嗎?其實,我認爲,這都是關於最小化浮動四捨五入誤差。這就是我所做的:優化浮點運算

typedef float T; 

T integrate(T left, T right, long N, T (*func)(T)) { 
    long i = 0; 
    T result = 0.0; 
    T interval = right - left; 
    for(i = 0; i < N; i++) { 
     result += func(left + interval * (i + 0.5)/N) * interval/N; 
    } 
    return result; 
} 
+1

'result + = func(left + interval *(i + 0.5)/ N)* interval'和'return result/N;' – 2013-03-16 18:47:58

+0

函數指針調用是否必要?它可以內聯嗎? – Mysticial 2013-03-16 18:48:20

+0

@Mysticial是的,這是必要的。但我不需要速度,我需要精確度,所以沒關係。 – 2013-03-16 18:51:02

回答

3

有很多方法可以避免或彌補浮點舍入(MM的建議,使用卡漢求和等)。然而,沒有理由這樣做,因爲由整合方案的誤差,舍入誤差爲絕對矮於;你不會得到更準確的積分,你會得到一個更準確的近似值,由中點規則計算出的錯誤結果。除非是在極其特殊的情況下,任何此類努力都被完全浪費。

+0

對於N = 18823,相對誤差爲-1,78814E-07(從0到Pi積分sin(x))。如果我將T變成雙倍,那就是1,16068E-09。差異並不大,是的。 – 2013-03-16 19:06:42

1

試試這個:

{ 
    long i = 0; 
    T result = 0.0; 
    T interval = right - left; 
    for(i = 0; i < N; i++) { 
     result += func(left + interval * (i + 0.5)/N); 
    } 
    return result * interval/N; 
} 
+0

沒有幫助或幫助很少。 – 2013-03-16 19:00:23

+2

這是他最好的,你可以得到,國際海事組織。它是唯一可以對精度進行優化的方法(也許是索引的計算,即i + 0.5部分 - 您可以使用while循環並遞增float而不是整數值。但是您不能期望32位浮點數的精確度太高 – 2013-03-17 06:37:12

3

I have a task to make the following function as precise as possible

你說你必須使用float,所以我想這個問題是不是四捨五入,而是約更準確地計算積分。

我還假設簡單增加N不是一個選項。

而不是使用中點規則,我的建議是考慮使用higher-order quadrature rule (trapezoid, Simpson's etc)

+2

完全正確。對於幾乎任何'func'的選擇,由於浮點舍入導致的錯誤歸因於集成方案。顯着提高準確性的唯一方法是使用更復雜的集成器。 – 2013-03-16 18:52:29

+0

哦,對不起,我編輯過問題:我必須使用中間矩形的方法。所以一切都是關於花車。我怎樣才能重新組合它們,增加,乘以等等來使計算更精確。 – 2013-03-16 18:55:11

1

如果要精確計算積分,請閱讀積分方案。一些家庭針織的例程不會給任何精度

"Numerical recipes"(有幾個版本,一個用於C)是高度重視。沒有親自看過它。