2017-07-26 97 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

相关问题