Java 中的舍入问题。为什么在这种情况下我没有得到预期的结果?

Rounding problem in Java. Why am i not getting the expected results in this case?

我有一个为 Minecraft 制作的插件。它用于大规模的末影龙战斗,根据造成的伤害将 EXP 公平地分配给每个人。

它可以工作,但有一个小问题使等式错过了经验。

代码如下:

private void divideExpAmongstPlayersBasedOnDamageDealt(int exp, Map<Player, Double> damageMap) {
    double totalDamageDealt = 0.0d;

    for (Double value : damageMap.values()) {
        totalDamageDealt += value;
    }

    while (exp > 0 && !damageMap.isEmpty()) {
        Player maxHitterInList = Collections.max(damageMap.entrySet(),
                Comparator.comparingDouble(Map.Entry::getValue)).getKey();

        double damageShare = damageMap.get(maxHitterInList) / totalDamageDealt;
        int expShare = (int) Math.round(exp * damageShare);

        if (expShare == 0)
            break;

        if (maxHitterInList.isOnline()) {
            sendPlayerMessage(maxHitterInList, damageShare, expShare);
            maxHitterInList.giveExp(expShare);
        }

        exp -= expShare;

        damageMap.remove(maxHitterInList);
    }
}

它找到最大的击球手,奖励他们他们的 EXP 份额并将他们从列表中删除,直到没有更多的 EXP 可以给予。

问题是它遗漏了分数,迫使我在 while 条件中添加 && !damageMap.isEmpty() 以避免异常。它总是准确地打印百分比(总和为 100)。

我认为它与 Math.round 函数有关,尽管我不知道如何调试它。当我手工计算时,它们就出来了。

示例(这确实发生了):暴民授予 10 exp。玩家 1 造成了 57% 的伤害,玩家 2 造成了 43%。百分比值打印正确,但 Player1 收到 6 EXP,Player2 收到 2??上次我检查 0.57 * 10 等于 5.7 = 60.43 * 10 等于 4.3 = 4.

我错过了什么?是否与 round 函数或 double 的工作方式有关?

谢谢

这不是四舍五入问题,而是您在计算中使用了错误的值。

你写的是"Last time i checked 0.57 * 10 equals 5.7 = 6 and 0.43 * 10 equals 4.3 = 4"但是你使用的公式是

int expShare = (int) Math.round(exp * damageShare);

然后您为循环的每次迭代更新 exp

exp -= expShare;

这意味着你的第二个玩家 exp 是 4 而不是你在你的例子中假设的 10 所以真正的计算是 0.43 * 2 四舍五入是 2

因此您需要将 while 条件中使用的变量与计算中使用的变量分开。