添加几个小浮点值会溢出到无穷大

时间:2015-01-17 14:39:11

标签: java infinity

我遇到了一个循环问题,这个循环应该将一些非常小的浮点值加在一起,最终产生加权平均值,如下所示:

    for(int k = 0; k < slopes.size(); k++){
        if(slopes.get(k).isClimbing() == false){
            float tempWeight = (slopes.get(k).getzDiff() / highestFallZ);
            weight += tempWeight;
            highestFallX += (slopes.get(k).getEndX() * tempWeight);
        }

        highestFallX = highestFallX / weight;
    }

它的作用基本上是从一个对象的一个​​属性产生一个权重(结果总是在0和1之间),然后通过该权重修改同一个对象的另一个属性,并将结果添加到一个正在运行的计数器中,最后除以权重之和。所有值和变量都是float类型。

现在我遇到的问题是,在几步之内,运行计数(highestFallX)呈指数级增长为-infinity。我已经运行了一些对角线,并且他们已经证明每个单独的值都在-1到-1 * 10 ^ -5之间(在与加权相乘之后)并且不超过60它们被加在一起,所以上溢和下溢都不应成为问题。为了比较,这里是循环的前几个步骤中最后一个添加值(LastFallX)和计数(HighestFallX)的列表:

LastFallX: -1.2650555E-4
HighestFallX: -1.2650555E-4
LastFallX: -6.3799386E-4
HighestFallX: -0.25996128
LastFallX: -4.602447E-4
HighestFallX: -87.01444
LastFallX: -0.0020183846
HighestFallX: -16370.462
LastFallX: -4.158747E-5
HighestFallX: -826683.3

从那以后,它会以指数方式持续增长,并且在大约10个循环内点击无穷大。在此循环期间,highFallX变量不会被其他任何内容引用或修改。

2 个答案:

答案 0 :(得分:0)

它有多精确?您可以简单地删除超过第三个小数的所有内容,以确保它不会遇到大量数字的问题

答案 1 :(得分:0)

表达平均值的一种方法是:

totalValue += nextValue * nextWeight;
totalWeight += nextWeight;
average = totalValue / totalWeight;

正如您所见,totalValue中容易出现溢出。

相反,您也可以这样做:

totalWeight += nextWeight;
average += ((nextValue * nextWeight) - average) / totalWeight;

在您的情况下,我认为可能如下:

for(int k = 0; k < slopes.size(); k++){
    if(slopes.get(k).isClimbing() == false){
        float tempWeight = (slopes.get(k).getzDiff() / highestFallZ);
        weight += tempWeight;
        float weightedValue = (slopes.get(k).getEndX() * tempWeight);
        float delta = weightedValue - highestFallX;
        highestFallX += delta / weight;
    }
}

但我仍在努力弄清楚你的加权平均值应该如何运作,所以我对最后一点有点不确定。