我们应该注意的任何陷阱Integer.MIN_VALUE == -Integer.MIN_VALUE == Math.abs(Integer.MIN_VALUE)

时间:2011-02-23 15:44:17

标签: java

我意识到下面的代码是真的

Integer.MIN_VALUE == -Integer.MIN_VALUE == Math.abs(Integer.MIN_VALUE)

这是因为当我们否定-2147483648时,它应该变为+2147483648。由于最大正整数可以用Java表示+2147483647,因此将发生整数溢出。发生溢出时,它再次变为-2147483648

我在想,对于上述情况,我们应该关注它吗?

5 个答案:

答案 0 :(得分:2)

编程历史中的每个功能,机制,功能,小工具,窗口小部件,窗口小部件和blidget都有输入和输出限制。

避免这种情况以及所有功能的陷阱不要假设没有限制

编辑:这并不意味着您无法使用这些限制,因为您肯定可以。只要确保任何'棘手','酷'或'hackish'得到它的文档份额,或者他们下一个进入代码(或者甚至是你)的人会怀疑wtf是否会继续。

答案 1 :(得分:2)

最大的陷阱是静音溢出,这是一个例子。

类似的例子。

Long.MIN_VALUE == -Long.MIN_VALUE;
0.0d == -0.0d
0.0f == -0.0f
Double.NaN != Double.NaN
Float.NaN != Float.NaN
Double.compare(Double.NaN, 0) == 1 but Double.NaN > 0 is false
Float.compare(Float.NaN, 0) == 1 but Float.NaN > 0 is false

FYI

Byte.MIN_VALUE != -Byte.MIN_VALUE;
Short.MIN_VALUE != -Short.MIN_VALUE;
Character.MIN_VALUE == -Character.MIN_VALUE;

答案 2 :(得分:1)

我无法想象编写任何依赖于溢出的代码的好理由。我将任何实际上都以这种方式工作的东西描述为陷阱本身,因为它的功能取决于系统中的缺点(即数字大小限制),而不是代码的清晰明确的含义(最大或最小值)。

答案 3 :(得分:0)

我能想到的唯一一个,就是如果你最终编写自己的绝对价值实现,你(天真地)做到了

return i < 0 ? -i : i;

(但请注意,Math.abs(Integer.MIN_VALUE)确实会返回否定结果(Integer.MIN_VALUE),因此在编写abs方法时,正确的行为是什么。

答案 4 :(得分:0)

我今天看到了这样的事情:

return Math.abs(obj.hashCode()) % partitions;

返回的分区号应该是非负的,因此Math.abs用于“确保”左侧是非负的,因为令人讨厌的%实现可能会返回负数。但是你可能已经猜到了这段代码被破坏了,因为hashCode()是一个整数,它可能会返回Integer.MIN_VALUE

一种可能的解决方法是对long进行转换,但我更喜欢将括号设置为略有不同:

return Math.abs(obj.hashCode() % partitions);

更新:实际上这个版本更好,因为它完全不依赖Math.abs

return (obj.hashCode() & Integer.MAX_VALUE) % partitions;

对于负哈希码,它将产生与上述版本不同的分区号,但如果按哈希码分区,通常你不应该关心它。