2

为什么java不能优雅地返回一些除以零的值,而是必须抛出异常?

我得到了ArrayIndexOutOfBoundsException:0 这是因为damageTaken 实际上是一个存储许多不同“损害”的值数组。

在java中我试图创建一个进度条。我们的示例:在赛车游戏中,通过将高度值设置为游戏结束前允许的最大伤害的百分比来造成伤害。

在程序开始时damageTaken = 0;

(damageTaken / maximumDamage)

将给出 0 - 1 之间的数字。

然后我只是将它乘以进度条的高度,以创建一个适当高度的填充条。

程序崩溃。我希望进度条的高度为零!

4

5 回答 5

14

您不是除以零,而是将零除以某物

完全允许取零的两半。答案是零。假设你有零个苹果。你把零苹果分给 Alice 和 Bob。Alice 和 Bob 现在都拥有零个苹果。

但是,您不能除以零。假设你有两个苹果。现在,你想把这些苹果给零个人。每个人得到多少个苹果?答案是不确定的,因此除以零是不可能的。

于 2010-09-28T22:38:48.390 回答
6
(damageTaken / maximumDamage)

仅当为零时,这才为您提供除以零异常maximumDamage

如果damageTaken为零,则没有问题。

于 2010-09-28T22:34:24.033 回答
4

只需为 0 添加一个特殊情况;

private int getProgress()
    if (damageTaken == 0) {
        return 0;
    } else {
        return (damageTaken / maximumDamage) * progress.getHeight();
    }
}

但是,(但它很大)您被 0 除的原因是因为maximumDamage是 0,而不是 damageTaken。所以,你可能真正想要的是:

private int getProgress()
    if (maximumDamage== 0) {
        return 0;
    } else {
        return (damageTaken / maximumDamage) * progress.getHeight();
    }
}
于 2010-09-28T22:34:59.597 回答
1

从概念上讲,让 4/0 产生一些任意数字并不比尝试将 2000000000 的计数加倍产生 -294967296 的计数更糟糕。然而,大多数处理器将忽略大多数类型的算术溢出,除非明确检查它,但不能忽略除以零的尝试,除非事先明确检查操作数(如果它们无效则跳过操作)。鉴于许多处理器都有“溢出”标志,没有什么可以阻止处理器指定尝试被零除应该只是设置溢出标志(成功的除法操作应该清除它);在这种情况下想要触发异常的代码可以这样做。

我怀疑这种不同行为的原因源于早期的计算。除法指令的硬件可以在余数小于除数时判断它是完整的。如果这种情况从未发生过,则指令可能会停止,直到通用监控时钟电路(如果出于某种原因停止执行指令时会发出故障信号)将其关闭。按照今天的标准,检测问题并在不停止 CPU 的情况下退出的硬件将是微不足道的,但在计算机由分立晶体管构建的时代,它更便宜,而且几乎同样有效,告诉程序员不要试图除以零,曾经

于 2014-01-21T23:55:38.973 回答
0

让我们停止谈论非法,就好像穿制服的数学警察要冲进房间一样。;) 对于这背后的数学推理,这个相关的问题很有用。

公平地问为什么,毕竟,现代编程平台没有以某种标准方式我们处理被零除的错误 - 但要回答这个问题:Java 和大多数其他平台一样,在以下情况下抛出错误发生除以零。一般来说,您可以:

  • 之前处理:在进行除法之前检查要用作分母的变量是否为零
  • 之后处理:您可以捕获发生被零除时抛出的异常并优雅地处理它。

请注意,作为良好实践,第二种方法仅适用于您不希望变量在正常系统操作下始终为零的情况。

所以是的,你需要一个特殊情况来处理这种情况。欢迎编程。;)

于 2010-09-28T22:45:54.383 回答