[英]Any trap which we should beware of Integer.MIN_VALUE == -Integer.MIN_VALUE == Math.abs(Integer.MIN_VALUE)
我意识到以下代码适用
Integer.MIN_VALUE == -Integer.MIN_VALUE == Math.abs(Integer.MIN_VALUE)
这是因为当我们取-2147483648
,它应该变成+2147483648
。 由于可以用Java表示的最大正整数为+2147483647
,因此将发生整数溢出。 发生溢出时,它再次变为-2147483648
。
我想知道, 对于上述情况,我们是否应该留意陷阱?
编程历史中的每个功能,机制,功能,小工具,小部件,小工具和blidget都有输入和输出限制。
为此和所有功能应避免的陷阱是,不要假设没有限制 。
编辑:这并不意味着您不能利用这些限制来发挥自己的优势,因为您肯定可以这样做。 只需确保所有“棘手”,“酷”或“ hackish”都得到了文档的共享,否则他们接下来要进入代码(甚至是您)的家伙都会想知道wtf还在继续。
最大的陷阱是倾斜溢流,这是一个示例。
类似的例子。
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;
我无法想象编写任何依赖于溢出的代码的充分理由。 我将描述实际上以这种方式起作用的任何东西本身就是一个陷阱,因为它的功能取决于系统中的缺点(即数字大小限制),而不是代码的明确含义(最大或最小值)。
我今天看到这样的东西:
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;
与上面的版本相比,它会为负哈希码生成不同的分区号,但是如果按哈希码进行分区,则通常不必理会。
我唯一能想到的是,如果您最终编写了自己的绝对值实现,而您(天真)
return i < 0 ? -i : i;
(但是请注意, Math.abs(Integer.MIN_VALUE)
确实返回了否定结果( Integer.MIN_VALUE
),因此编写abs方法时,正确的行为Math.abs(Integer.MIN_VALUE)
讨论。)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.