简体   繁体   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)

I realize the below code holds true 我意识到以下代码适用

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

This is because when we negate -2147483648 , it should become +2147483648 . 这是因为当我们取-2147483648 ,它应该变成+2147483648 Since the maximum positive integer can be represented in Java is +2147483647 , integer overflow will occur. 由于可以用Java表示的最大正整数为+2147483647 ,因此将发生整数溢出。 When overflow occur, it becomes -2147483648 again. 发生溢出时,它再次变为-2147483648

I was wondering, is there any trap we should keep an eye on it, for the above situation? 我想知道, 对于上述情况,我们是否应该留意陷阱?

Every function, mechanism, feature, gadget, widget, fidget, and blidget in the history of programming has input and and output limitations. 编程历史中的每个功能,机制,功能,小工具,小部件,小工具和blidget都有输入和输出限制。

The trap to avoid for this, and for all features, is do not assume there are no limits . 为此和所有功能应避免的陷阱是,不要假设没有限制

Edit: This doesn't mean you can't use these limits to your advantage, because you most certainly can. 编辑:这并不意味着您不能利用这些限制来发挥自己的优势,因为您肯定可以这样做。 Just make sure that anything 'tricky', 'cool', or 'hackish' gets it's share of documentation, or they next guy to come into the code (or even you) is going to wonder wtf is going on. 只需确保所有“棘手”,“酷”或“ hackish”都得到了文档的共享,否则他们接下来要进入代码(甚至是您)的家伙都会想知道wtf还在继续。

The biggest trap is the slient overflow of which this is an example. 最大的陷阱是倾斜溢流,这是一个示例。

Similar examples. 类似的例子。

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 FYI

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

I can't imagine a good reason for writing any code that depends on overflow. 我无法想象编写任何依赖于溢出的代码的充分理由。 I'd describe anything that actually worked that way as a trap in itself, because it's functioning is dependent on shortcomings in the system (ie numeric size limits) rather than the clear and explicit meaning of the code (largest or smallest value). 我将描述实际上以这种方式起作用的任何东西本身就是一个陷阱,因为它的功能取决于系统中的缺点(即数字大小限制),而不是代码的明确含义(最大或最小值)。

I saw something like this today: 我今天看到这样的东西:

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

The returned partition number should be non-negative so Math.abs is used to "ensure" that the left side is non-negative, since the obnoxious % implementation could return a negative number otherwise. 返回的分区号应为非负数,因此Math.abs用于“确保”左侧为非负数,因为令人讨厌的%实现可能会返回负数。 But as you might have guessed this code is broken since hashCode() is an integer and it might return Integer.MIN_VALUE . 但正如您可能已经猜到的那样,此代码已损坏,因为hashCode()是整数,并且可能返回Integer.MIN_VALUE

One possible fix would be to do a cast to long but I prefer to just set the parenthesis a little different: 一种可能的解决方法是将转换强制转换为long但是我更愿意将括号设置得稍微不同:

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

Update: Actually this version is better since it doesn't rely on Math.abs at all: 更新:实际上,此版本更好,因为它完全不依赖Math.abs

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

It will yield different partition numbers for negative hash codes than the version above, but normally you shouldn't care about that if you partition by hash code. 与上面的版本相比,它会为负哈希码生成不同的分区号,但是如果按哈希码进行分区,则通常不必理会。

The only one I can come up with, is if you end up writing your own absolute-value implementation, where you (naively) do 我唯一能想到的是,如果您最终编写了自己的绝对值实现,而您(天真)

return i < 0 ? -i : i;

(Note however, that Math.abs(Integer.MIN_VALUE) indeed returns a negative result ( Integer.MIN_VALUE ), so what is the correct behavior is up for discussion when writing an abs-method.) (但是请注意, 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