溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

為什么Java中負數的絕對值不一定是正數

發布時間:2021-07-29 13:39:06 來源:億速云 閱讀:142 作者:chen 欄目:開發技術

這篇文章主要講解了“為什么Java中負數的絕對值不一定是正數”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“為什么Java中負數的絕對值不一定是正數”吧!

絕對值是指一個數在數軸上所對應點到原點的距離,所以,在數學領域,正數的絕對值是這個數本身,負數的絕對值應該是他的相反數。

這幾乎是每個人都知道的。

在Java中,想要獲得有個數字的絕對值,可以使用java.lang.Math中的abs方法,這個類共有4個重載的abs方法,分別是:

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;
}

以上4個方法分別返回int、long、float、double類型的絕對值,方法里面的邏輯也簡單,無非就是整數直接返回,負數取相反數返回。

所以,基于以上所有的知識,我們經常會直接使用Math.abs來對一個數字取絕對值。

在我們的代碼中,也有很多這樣的例子。

比如,我們需要用訂單號做分庫分表,但是訂單號是字符串類型,所以,我們就需要取得這個字符換的hashCode,因為hashCode可能是負數,所以然后再對hashCode取絕對值,再用這個值去對分表數取模:

Math.abs(orderId.hashCode()) % 1024;

但是,上面這個邏輯是有問題的?。?!

因為在極特殊情況下,上面的代碼會得到一個負數的值。

**這個極特殊情況下就是當hashCode是Integer.MIN_VALUE,即整數能表達的最小值的時候,**可以代碼驗證下:

public static void main(String[] args) {
    System.out.println(Math.abs(Integer.MIN_VALUE));
}

執行以上代碼,得到的結果是:

-2147483648

很明顯,這是個負數?。?!

為什么會這樣呢?

這要從Integer的取值范圍說起,int的取值范圍是-2^31 —— (2^31) - 1,即-2147483648 至 2147483647

那么,當我們使用abs取絕對值時候,想要取得-2147483648的絕對值,那應該是2147483648。

但是,2147483648大于了2147483647,即超過了int的取值范圍。這時候就會發生越界。

2147483647用二進制的補碼表示是:

01111111 11111111 11111111 11111111

這個數 +1 得到:

10000000 00000000 00000000 00000000

這個二進制就是-2147483648的補碼。

雖然,這種情況發生的概率很低,只有當要取絕對值的數字是-2147483648的時候,得到的數字還是個負數。

那么,如何解決這個問題呢?

既然是以為越界了導致最終結果變成負數,那就解決越界的問題就行了,那就是在取絕對值之前,把這個int類型轉成long類型,這樣就不會出現越界了。

如,前面我們的分表邏輯修改為

Math.abs((long)orderId.hashCode()) % 1024;

就萬無一失了。

大家可以執行下以下代碼:

public static void main(String[] args) {
    System.out.println(Math.abs((long)Integer.MIN_VALUE));
}

得到的結果就是:

2147483648

以上,就是今天要介紹的知識點了。

但是,一定要記得,對long類型取絕對值其實也可能存在這個情況哦!只不過發生的概率就更低了,但是只要他存在,就有可能發生哦!

ps:下面看下Java 中怎么把負數轉換為正數?

要將負數轉換為正數(這稱為絕對值),請使用Math.abs()。此Math.abs()方法的工作方式如下:“number = (number < 0 ? -number : number);”。
看一個完整的例子:

package com.mkyong;
  
public class app{
   
  public static void main(String[] args) {
     
    int total =1 +1 +1 +1 + (-1);
     
    //output 3
    System.out.println("Total : " + total);
     
    int total2 =1 +1 +1 +1 + Math.abs(-1);
     
    //output 5
    System.out.println("Total 2 (absolute value) : " + total2);
     
  }
   
}

輸出量

Total :3
Total2 (absolute value) :5

在這種情況下,Math.abs(-1)會將負數1轉換為正數1?! ?/p>

感謝各位的閱讀,以上就是“為什么Java中負數的絕對值不一定是正數”的內容了,經過本文的學習后,相信大家對為什么Java中負數的絕對值不一定是正數這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女