繁体   English   中英

我们应提防Integer.MIN_VALUE == -Integer.MIN_VALUE == Math.abs(Integer.MIN_VALUE)的任何陷阱

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM