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

标签 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) 呈指数增长到无穷大。我进行了一些对比分析,结果表明,每个单独的附加值都在 -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 个循环内达到无穷大。在此循环期间,highestFallX 变量不会被任何其他内容引用或修改。

最佳答案

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

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;
    }
}

但我仍在尝试准确计算出加权平均值的工作原理,因此我对最后一点有点不确定。

关于java - 添加几个小的浮点值会溢出到无穷大,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28000558/

相关文章:

java - 可以为现有流程创建流程对象吗?

c# - Java 中的 vb.net 'friend' 关键字等价于什么?

python - 在 python 代码中生成的无穷大

java - 在一定时间后退出程序 - Java

java - 如何找出在 Swing 应用程序中消耗 KeyPressed 事件的内容?

java - Android 中的 Dialog 内的 setAdapter() 无法弹出吗?

math - 榆树有无穷大的常数吗?

svn - 用 pysvn 做一个 'svn update --set-depth=infinity'

mysql - Infinity、ActiveRecord 和 MySQL : storage and comparison

c# - 将无穷大数学行为添加到 Decimal