簡體   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