更大。如果我有一個分配龍+長不超過Long.MAX_VALUE
Long c = a + b;
有沒有一種簡單的方法來檢查a + b
並不是越大/比Long.MAX_VALUE
/Long.MIN_VALUE
小?
更大。如果我有一個分配龍+長不超過Long.MAX_VALUE
Long c = a + b;
有沒有一種簡單的方法來檢查a + b
並不是越大/比Long.MAX_VALUE
/Long.MIN_VALUE
小?
使用Guava,它是那樣簡單
long c = LongMath.checkedAdd(a, b); // throws an ArithmeticException on overflow
是,我想認爲,可讀性很強確實如此。 (LongMath Javadoc here。)
爲了公平起見,我會提到Apache Commons提供了ArithmeticUtils.addAndCheck(long, long)
。
如果你想知道他們是如何工作的,那麼,答案是位兩輪牛車爲番石榴的一行:結果不會溢出,如果(a^b) < 0 | (a^(a + b)) >= 0
。這是基於技巧,兩個數字的按位異或是非負當且僅當它們具有相同的符號。
所以(a^b) < 0
是真的如果a
和b
有不同的跡象,如果是這樣的話,它永遠不會溢出。或者,如果(a^(a + b)) >= 0
,則a + b
具有相同的符號爲a
,所以也沒溢出,變爲負值。
(有關更多的技巧是這樣,調查可愛的書Hacker's Delight)
Apache使用基礎上的a
和b
符號更復雜的個案。
+1番石榴。即使比較(如我最初所建議的)可能有效(儘管我太困了,不能正確地考慮它),但願意使用即用功能 – Bozho 2012-01-29 22:28:29
完全披露:我是「LongMath」的作者,其餘的番石榴的common.math包...但@Bozho是正確的,它通常更好地依賴庫代碼而不是滾動自己的實現。(特別是,這個代碼已經經過測試*非常詳盡,所以你不必!) – 2012-01-29 22:32:33
非常酷。添加另一個完整的庫可能會導致這樣一個簡單的情況(檢測溢出在這種情況下是微不足道的),但如果你已經*使用番石榴... – 2012-01-29 22:34:32
一種選擇是使用BigInteger
類做精確的計算,然後檢查結果是否比有問題的值大於或更小。例如:
if (BigInteger.valueOf(a).add(BigInteger.valueOf(b)).compareTo(BigInteger.valueOf(Long.MAX_VALUE) > 1) {
/* Overflow occurred. */
} else {
/* No overflow occurred.
}
希望這有助於!
如果你打算繼續使用全功能'BigInteger',你可以檢查'myBigInt.bitLength()
@LouisWasserman正確,因爲小於,否則它會被一個關閉。我不認爲這兩個選項中的任何一個都是可讀的,並且其中一個答案只需要Long.MAX_VALUE,而不是Long.MIN_VALUE ... – 2012-01-29 22:42:24
一致認爲這比它的可讀性差。作爲參考,雖然我會說BigInteger方法是檢查* multiplication *溢出的最可讀方法,如果您不願意使用庫。 – 2012-01-29 22:44:29
簡約路線:
if(a/2+b/2+(a&b&1)>long.MAX_VALUE/2||a/2+b/2<long.MIN_VALUE/2)...
你只需要希望它不會優化(a+b)/2
我不相信這是正確的。取a = Long.MAX_VALUE和b = 1。然後,如果添加兩個值,那麼顯然會發生溢出,但是如果將它們減半,a/2 = Long.MAX_VALUE/2和b/2 = 0,那麼a/2 + b/2 <= Long.MAX_VALUE。 – templatetypedef 2012-01-29 22:38:24
@templatetypedef我修復了這個小技巧(增加了溢出) – 2012-01-29 23:20:04
這只是一個問題,如果它們具有相同的符號(和都!0
)因爲否則你是安全的溢出。如果發生溢出,結果的符號將會翻轉。所以:
long r = a + b;
if ((a < 0 && b < 0 && r >= 0) ||
(a > 0 && b > 0 && r <= 0)) {
// Overflow occurred
}
註冊了,最簡單,最易讀和最好的方法。希望該課程不會採用更「優化」的數學方法。 – 2012-01-29 22:38:32
@owlstead,如果編譯器足夠聰明,它可以使用CPU「攜帶」標誌,所以解決方案就夠用了。當天返回的唯一算法是通過進位完成的。 – bestsss 2012-01-29 22:42:54
Upvoted爲最適合家庭作業的解決方案。 – 2012-01-29 22:50:32
請參閱問題文本框右側的**如何格式**框以及它上方的** [?] **鏈接(以及其下方的預覽)正確設置問題的格式。 – 2012-01-29 22:18:56
在彙編,將有可能檢查* *攜帶國旗? – 2012-01-29 22:22:08
我刪除了[功課]標籤,作爲OP的評論跟帖,這是隻有在那裏偶然提及。 – 2012-01-29 23:01:01