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 = 6
和 0.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
条件中使用的变量与计算中使用的变量分开。
我有一个为 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 = 6
和 0.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
条件中使用的变量与计算中使用的变量分开。