2017-10-14 81 views
1

經過一系列浮點算術運算後,是否存在小於等於浮點數的等值比較的「最佳做法」?加法和減法後的浮點和小於等於

我在R中有下面的例子,雖然這個問題不僅適用於R,而且適用於任何使用浮點的語言。我有一個雙重x = 1,我應用了一系列的加法和減法。最後x應該只是一個,但不是由於浮點運算(來自我收集的)。這裏是例子

> stop_times <- seq(0.25, 2, by = .25) 
> expr <- expression(replicate(100,{ 
+ x <- 1 
+ 
+ for(i in 1:10){ 
+  tmp <- rexp(1, 1) 
+  n <- sample.int(1e2, 1) 
+  delta <- tmp/n 
+  for(j in 1:n) 
+  x <- x - delta 
+  x <- x + tmp 
+ } 
+ 
+ # "correct" answer is 4 
+ which.max(x <= stop_times) 
+ })) 
> eval(expr) 
    [1] 5 5 5 4 4 4 5 5 5 4 5 4 4 4 5 5 4 4 5 4 5 4 5 4 5 5 5 4 4 4 4 4 4 4 4 4 5 5 5 5 5 4 5 4 5 5 5 4 4 5 5 5 4 4 5 5 5 4 4 4 4 4 4 
[64] 5 4 4 4 5 5 5 4 4 4 5 4 4 4 4 4 4 4 4 5 5 5 5 4 4 4 5 5 5 5 5 4 4 4 5 5 4 

A(幼稚?)解決方案是一些任意小的正數增加了不平等的右側如下

some_arbitrary_factor <- 100 
stop_times <- seq(0.25, 2, by = .25) + 
    some_arbitrary_factor * .Machine$double.eps 
eval(expr) 
    [1] 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 
[64] 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 

這是「最佳實踐」和如果有的話,有如何選擇some_arbitrary_factor的指導方針?

我的具體問題是,我有時間段$(t_0,t_1],(t_1,t_2),\ dots $,並且需要查找給定觀察值$ x $在哪個週期內。$ x $在進行了一系列浮點算術運算後,可能已經被設置爲一個邊界$ t_i $,如果執行了精確操作,結果應該是$ t_i $

+0

如果您想更詳細地介紹這一點,Donald knuth的計算機編程藝術,第3章對漂浮點的黑色藝術進行了很好的概述。在R中,我們有'all.equal'作爲測試近似等式的方式。所以你可以使用像'(x dww

+0

我知道'all.equal'函數。缺省值是scale = NULL(缺省值)的_Numerical比較通常是在相對差分尺度上,除非目標值接近零:首先,計算兩個數值向量的平均絕對差值。如果這小於容差或不是有限的,則使用絕對差異,否則相對差異由平均絕對目標值縮放。其中'tolerance'默認爲'sqrt(.Machine $ double.eps)'。我不確定這是否是一種常見做法? –

回答

5

不,沒有最佳實踐。不可能,因爲幾乎所有的浮點計算都會引入一些舍入誤差,並且對於不同的應用程序,誤差的後果是不同的。

通常,軟件將執行一些計算,但是,由於舍入誤差(或其他問題),會產生近似值x'。當比較浮點數,你要問一些問題有關X,如「是X < 1?」或「X = 3.1415926 ......?」所以,你要解決的問題是「如何我用X「來回答這個問題有關X?」

沒有通用的解決方案這一點。即使小於1,某些錯誤可能會產生大於1的「x」。即使x大於1,某些錯誤可能產生小於1的'。任何具體實例取決於在計算x'時生成的錯誤信息以及要回答的具體問題。

有時候一個全面的分析可以證明某些關於x的問題可以用x'來回答。例如,在某些情況下,我們可以讓我們知道手藝計算,如果X '< 1,然後X < 1.或許,如果X' < 0.99875,然後X < 1。假設我們分析了我們用於計算的計算結果x',並且可以顯示最終的誤差小於.00125。然後,如果X '< 0.99875,那麼我們就知道X < 1,並且,如果X'> 1.00125,然後X> 1。但是,如果0.99875 < X「< 1.00125,那麼我們不知道是否x> 1或x < 1.我們在那種情況下做什麼?對於你的應用程序來說,更好的方式是採取x < 1或者路徑x> 1的路徑嗎?答案是針對每個應用程序的,並且沒有一般的最佳實踐。

我會補充說明,發生的舍入誤差的數量在應用程序和應用程序之間差別很大。這是因爲四捨五入錯誤可以以各種方式混合。一些具有少量浮點運算的應用程序將會以小錯誤達到結果。一些具有許多浮點運算的應用程序也會以適度的錯誤達到結果。但某些行爲會導致計算錯位併產生災難性錯誤。所以處理舍入錯誤是每個程序的自定義問題。

+0

這就是我所想的。雖然,這確實很好。 –