2017-07-26 96 views
0

當我有兩個(小)數字最小值和最大值並嘗試使用以下代碼獲取介於0和1之間的值時,是否可以得到小於0或更大的值比1?將一個小範圍除以另一個小範圍時的浮點錯誤

double min, max, min2, max2, mid, result; 
// min2 < max2 is a subrange of min < max with min2 >= min and max2 <= max 
// where max-min may be very small, which means max2-min2 will be very small as well. 
mid = (min2+max2)/2.0; 
result = (mid - min)/(max-min) 

我有問題,我得到更大的值大於1時min, max是浮動而min2, max2是雙打。 現在我讓他們都變數double,但我仍然不確定浮點錯誤是否會產生錯誤的結果。

後來我想通過使用

const int MAX=63; 
double array[64]; 
int index = (int)(result*MAX); 
array[index]; 

用結果來細分號碼範圍,並希望得到準確的指標甚至小的差異。

其中i混合雙打時得到了問題並浮舉個例子:

NUM_BINS = 64 
min = -5.00958252 
max = -5.00958014 
min2 = -5.0095801960014716 
max2 = -5.0095799398356107 
mid = (max2+min2)/2.0 
mid - min = 2.4516127083984429e-06 
(mid - min)/(max - min)) * (NUM_BINS - 1) = 64.781696632504463 
+1

考慮到你沒有給出任何關於'min2'和'max2'相對於'min'和'min'的任何信息,你能給出一個數學的論證,爲什麼'result' *不應該*能夠超過'1', max'? – EOF

+0

max2 <= max並且min2> = min意味着max2-min2 <= max-min。真正的問題是浮點算術,可能會發生奇怪的事情。 – allo

+0

將此添加爲問題的顯式註釋。 – allo

回答

2

假設IEEE754算術,如果最小和最大足夠接近,則差值是精確的。

平均用於計算中間點不一定是精確的(由2分割精確假設沒有下溢,但總和不),但以下表達式都是真:

min2 <= mid 
mid <= max2 

mid-min將是精確(因此<= (max-min)),所以最後的不精確操作/將舍入到最接近的浮點值。由於確切值爲< = 1,因此沒有理由將其舍入大於1.

如果編譯器決定使用過量精度,上面的關係仍然成立。當你使用混合精度時會發生什麼,我不太清楚......如果你能展示精確值(十六進制格式),我會好奇的。

+0

我在問題中添加了值(不是十六進制,它們就像我在調試時保存它們一樣)。 – allo

+0

好的,但在你的示例max

+0

是的,這個例子顯然是錯誤的。它混合浮動和雙重,這是造成這裏的問題。但我不確定使用相同的浮點類型是否真的解決了這個問題,或者是否可能再次發生某些(較小的)值。 – allo

相關問題