将一个小范围除以另一个小范围时出现浮点错误

时间:2017-07-26 22:48:41

标签: floating-point

当我有两个(小)数字min和max并尝试使用以下代码得到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)

我遇到了问题,当min, max浮动而min2, max2为双倍时,我的值大于1。 现在我将它们变为double个变量,但我仍然不确定浮点错误是否会产生错误的结果。

稍后我想使用结果通过

细分数字范围
const int MAX=63;
double array[64];
int index = (int)(result*MAX);
array[index];

并希望获得准确的指数,即使是微小的差异。

我在混合双打和浮动时遇到问题的例子:

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 个答案:

答案 0 :(得分:2)

假设IEEE754算术,如果min和max足够接近,则差异是准确的。

计算中点的平均值不一定是精确的(假设没有下溢,则除以2是精确的,但总和不是),但以下表达式都是正确的:

min2 <= mid
mid <= max2

mid-min将是精确的(因此<= (max-min)),因此最后的不精确操作/将舍入到最接近的浮点值。由于精确值是&lt; = 1,因此没有理由将其舍入到1以上。

如果编译器决定使用过多的精度,则上述关系仍然有效。使用混合精度时可能会发生什么,我看不太清楚......如果你能展示出精确的值(十六进制格式),我会很好奇。