在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型別取絕對值其實也可能存在這個情況哦!只不過發生的機率就更低了,但是隻要他存在,就有可能發生哦!
原文來自:
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69955379/viewspace-2784527/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 在Java中,負數的絕對值竟然不一定是正數!!!Java
- 自己對Java中if變數賦值的理解Java變數賦值
- 求正整數
- 陣列中未出現的最小正整數陣列
- 求陣列中未出現的最小正整數陣列
- javascript獲取數字的絕對值程式碼例項JavaScript
- 詳解Java判斷是否是整數,小數或實數的正規表示式Java
- Java中計算整數中唯一數字數量的3種方法Java
- Java列印所有整數中2的乘方Java
- JQuery 判斷 正整數jQuery
- matlab中怎樣隨機生成一個最大值為N的正整數??Matlab隨機
- Java判斷一個正整數是不是2的乘方Java
- js 將負數或小數轉成正整數JS
- Input 輸入框中 只能輸入正整數
- 【c語言】將正數變成對應的負數,將負數變成對應的正數C語言
- 劍指offer面試題11 數值的整數次方面試題
- 【演算法詳解】求解數值的整數次方演算法
- 醜數,即只包含質因數 2、3 和 5 的正整數。
- double型別中可精確表達的最大正整數型別
- 【C語言】編寫一個函式,將一個數字字串轉換成該字串對應的數字(包括正整數、負整數)。C語言函式字串
- jQuery實現的規定文字框中只能輸入正整數jQuery
- Java中數字的四捨五入和取整Java
- 【leetcode】劍指 Offer 16. 數值的整數次方LeetCode
- 【JAVA習題六】輸入兩個正整數m和n,求其最大公約數Java
- L1-025 正整數A+B 分數 15
- 正整數表單校驗規則
- Java整數緩衝區Java
- 演算法之絕對眾數演算法
- python將輸入的一個正整數分解質因數(map)Python
- JavaScript正規表示式校驗非零的正整數例項JavaScript
- Python:判斷一個正整數是否為迴文數Python
- JavaScript正規表示式校驗非正整數例項JavaScript
- 驗證正整數正規表示式程式碼例項
- C#驗證是不是正整數 正規表示式C#
- 如何查詢總和等於給定數字的整數陣列中的所有對陣列
- 記錄在 jmeter 介面測試中 json 返回數值幾種特殊正則提取JMeterJSON
- C/C++模運算(正負整數)C++
- 排序演算法-N個正整數排序排序演算法