我意识到下面的代码是真的
Integer.MIN_VALUE == -Integer.MIN_VALUE == Math.abs(Integer.MIN_VALUE)
这是因为当我们否定-2147483648
时,它应该变为+2147483648
。由于最大正整数可以用Java表示+2147483647
,因此将发生整数溢出。发生溢出时,它再次变为-2147483648
。
我在想,对于上述情况,我们应该关注它吗?
答案 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;
对于负哈希码,它将产生与上述版本不同的分区号,但如果按哈希码分区,通常你不应该关心它。