注意:在Java中(zhōng),負數的絕對值竟然不一定是正數

 行業動态     |      2021-07-27 14:50
絕對值是指一個數在數軸上所對應點到原點的距離,所以,在數學(xué)領域,正數的絕對值是這個數本身,負數的絕對值應該是他(tā)的相反數。
 
這幾乎是每個人都知道的。
 
在Java中(zhōng),想要獲得有(yǒu)個數字的絕對值,可(kě)以使用(yòng)java.lang.Math中(zhōng)的abs方法,這個類共有(yǒu)4個重載的abs方法,分(fēn)别是:
 
public static int abs(int a) {
    return (a < 0) ? -a : a;
}
 
public static long abs(long a) {
    return (a < 0) ? -a : a;
}
 
public static float abs(float a) {
    return (a <= 0.0F) ? 0.0F - a : a;
}
 
public static double abs(double a) {
    return (a <= 0.0D) ? 0.0D - a : a;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
以上4個方法分(fēn)别返回int、long、float、double類型的絕對值,方法裏面的邏輯也簡單,無非就是整數直接返回,負數取相反數返回。
 
所以,基于以上所有(yǒu)的知識,我們經常會直接使用(yòng)Math.abs來對一個數字取絕對值。
 
在我們的代碼中(zhōng),也有(yǒu)很(hěn)多(duō)這樣的例子。
 
比如,我們需要用(yòng)訂單号做分(fēn)庫分(fēn)表,但是訂單号是字符串類型,所以,我們就需要取得這個字符換的hashCode,因為(wèi)hashCode可(kě)能(néng)是負數,所以然後再對hashCode取絕對值,再用(yòng)這個值去對分(fēn)表數取模:
 
Math.abs(orderId.hashCode()) % 1024;
1
但是,上面這個邏輯是有(yǒu)問題的!!!
 
因為(wèi)在極特殊情況下,上面的代碼會得到一個負數的值。
 
**這個極特殊情況下就是當hashCode是Integer.MIN_VALUE,即整數能(néng)表達的最小(xiǎo)值的時候,**可(kě)以代碼驗證下:
 
public static void main(String[] args) {
    System.out.println(Math.abs(Integer.MIN_VALUE));
}
1
2
3
執行以上代碼,得到的結果是:
 
-2147483648
1
很(hěn)明顯,這是個負數!!!
 
為(wèi)什麽會這樣呢(ne)?
 
這要從Integer的取值範圍說起,int的取值範圍是-2^31 —— (2^31) - 1,即-2147483648 至 2147483647
 
那麽,當我們使用(yòng)abs取絕對值時候,想要取得-2147483648的絕對值,那應該是2147483648。
 
但是,2147483648大于了2147483647,即超過了int的取值範圍。這時候就會發生越界。
 
2147483647用(yòng)二進制的補碼表示是:
 
01111111 11111111 11111111 11111111
 
這個數 +1 得到:
 
10000000 00000000 00000000 00000000
 
這個二進制就是-2147483648的補碼。
 
雖然,這種情況發生的概率很(hěn)低,隻有(yǒu)當要取絕對值的數字是-2147483648的時候,得到的數字還是個負數。
 
那麽,如何解決這個問題呢(ne)?
 
既然是以為(wèi)越界了導緻最終結果變成負數,那就解決越界的問題就行了,那就是在取絕對值之前,把這個int類型轉成long類型,這樣就不會出現越界了。
 
如,前面我們的分(fēn)表邏輯修改為(wèi)
 
Math.abs((long)orderId.hashCode()) % 1024; 
1
就萬無一失了。
 
大家可(kě)以執行下以下代碼:
 
public static void main(String[] args) {
    System.out.println(Math.abs((long)Integer.MIN_VALUE));
}
1
2
3
得到的結果就是:
 
2147483648
1
以上,就是今天要介紹的知識點了。
 
但是,一定要記得,對long類型取絕對值其實也可(kě)能(néng)存在這個情況哦!隻不過發生的概率就更低了,但是隻要他(tā)存在,就有(yǒu)可(kě)能(néng)發生哦.
————————————————
版權聲明:本文(wén)為(wèi)CSDN博主「Hollis Chuang」的原創文(wén)章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文(wén)出處鏈接及本聲明。
原文(wén)鏈接:https://blog.csdn.net/hollis_chuang/article/details/119104584