Java中与&&不一致和被零除错误

Posted

技术标签:

【中文标题】Java中与&&不一致和被零除错误【英文标题】:Inconsistencies with && and divide-by-zero error in Java 【发布时间】:2013-06-19 16:37:24 【问题描述】:

我开始使用 Java,但遇到了一些不一致的问题。为什么会这样:

if ((d != 0) && (n / d < 3)) 
    compute(a, d);

但如果我这样做:

if ((n / d < 3) && (d != 0)) 
    compute(a, d);

我收到此错误:

Exception in thread "main" java.lang.ArithmeticException: / by zero
    at compute.main(compute.java:63)

【问题讨论】:

投票结束,因为您似乎确实认为您得到什么确切的错误以及从哪里得到对我们来说并不重要。 我添加了错误信息,这样更好吗? +1 用于添加错误消息。 由于编辑,不再是关闭的候选人。 @Ingo 我建议将来先发表您的批评,并让他们有机会在如此匆忙地投票结束之前解决它。 @user2512229 下次你会被处决;) 【参考方案1】:

Java 使用Short-Circuit Logic 计算表达式。这意味着对于&amp;&amp;,如果左边的表达式是false,那么Java 不会费心计算右边的表达式(因为整个表达式已经保证为假)。

在你的第一个例子中,如果d == 0,那么d != 0 是假的,所以它不会评估n / d。在您的第二个示例中,如果 d == 0,则评估 n / d &lt; 3 会给您除以零错误。

【讨论】:

另外:这种“短路”行为并不是 Java 特有的——大多数编程语言都支持它。 另请参阅 Java 语言规范:Conditional-And Operator && - 条件与运算符 && 类似于 & (§15.22.2),但仅当其左操作数的值为手操作数为真。 哇,这真的很清楚! 这同样适用于 ||。如果左侧操作数为真,则不会计算右侧操作数。 晦涩的语言注释:& 和 | 不会发生短路。【参考方案2】:

在您的第一个示例中,由于short circuit evaluation,当d == 0 时,编译器认为它不需要评估n/d,因为false &amp;&amp; true 仍然是错误的。

如果你改变条件,你最终会先评估n/d,然后才能知道 d 是否为零。你导致的是一个错误,因为被零除。

【讨论】:

【参考方案3】:

这不是矛盾。任何从 C 语言(C++、Java 和许多其他语言)派生的语言都以这种方式运行(将 && 和 || 运算符短路)。

如果您希望双方都进行评估,请使用 & 和 | (与 && 和 || 相比)。

【讨论】:

以上是关于Java中与&&不一致和被零除错误的主要内容,如果未能解决你的问题,请参考以下文章

接近零的浮点值会导致被零除的错误吗?

我在python中得到“被零除”错误,但我不知道为什么

避免在 PostgreSQL 中被零除

除了被零除之外,还都有哪些情况会发生浮点异常?

SET ANSI_WARNINGS { ON | OFF }

gitlab迁移遇到的版本不一致和无法导入问题