日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

java int 和 long比较大小会_解析java的addExact()与multiplyExact()

發布時間:2025/3/11 14 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java int 和 long比较大小会_解析java的addExact()与multiplyExact() 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

java的加法在數字過大時是會溢出的,今天就遇到一個問題,要實現一個溢出時會拋出異常的加法函數。

這個問題細細一想卻是復雜的很:不僅要考慮加法,輸入參數還可以是負數反向溢出。好在java已經實現了該功能,直接閱讀Math庫的源碼。

public static long addExact(long x, long y) {long r = x + y;// HD 2-12 Overflow iff both arguments have the opposite sign of the resultif (((x ^ r) & (y ^ r)) < 0) {throw new ArithmeticException("long overflow");}return r; }

這個寫法相當巧妙,首先我們知道java的int型在計算機中作為補碼存儲,而第一位是符號位(有時候會涉及到大小端存儲,此處不影響敘述),直接決定了數字的正負。整個代碼表面上是在對整個int做處理,實際有用的只有x y r的符號位而已。(0:正號 1:負號)下面列出x y r的符號位的真值表:

根據真值表反推,溢出只有“兩個負數相加變成正數“和”兩個正數相加變成負數“兩種情況。考慮值域后確實如此。

在學習addExact()時,我意外收獲了另一份有趣的代碼,就是multiplyExact()。

public static int multiplyExact(int x, int y) {long r = (long)x * (long)y;if ((int)r != r) {throw new ArithmeticException("integer overflow");}return (int)r; }public static long multiplyExact(long x, long y) {long r = x * y;long ax = Math.abs(x);long ay = Math.abs(y);if (((ax | ay) >>> 31 != 0)) {// Some bits greater than 2^31 that might cause overflow// Check the result using the divide operator// and check for the special case of Long.MIN_VALUE * -1if (((y != 0) && (r / y != x)) ||(x == Long.MIN_VALUE && y == -1)) {throw new ArithmeticException("long overflow");}}return r; }

int型的轉成了long做暴力判斷,而long就沒辦法了。

首先用((ax | ay) >>> 31 != 0)做了一個判斷,等價于ax>2^31 || ay > 2^31。做這個判斷一方面是為了排除不會溢出的情況,另一方面也暗示接下來的步驟比較費時。

果然接下來直接用除法做了逆運算。。這個思路倒是非常粗暴有效,但是其中的額外情況 x == Long.MIN_VALUE && y == -1 也算是一個非常微妙的漏洞。由于溢出,這個式子相乘的結果是Long.MAXVALUE+1,也就是Long.MINVALUE。但是,除法也溢出成了Long.MAXVALUE+1,還是Long.MINVALUE,導致變成了需要額外判斷的特例。

標準庫都是一群大牛精簡出來的代碼,因為一個特例導致多了這樣一行代碼,cpu周期多走了幾個。想到他們殫精竭慮也沒法把這個特例從代碼中消除的樣子,可以說是十分有趣了。

總結

以上是生活随笔為你收集整理的java int 和 long比较大小会_解析java的addExact()与multiplyExact()的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。