2012-09-10 56 views
5

我在檢測兩個數的和/乘是否超過長整數的最大值時遇到問題。
示例代碼:java數量超過long.max_value - 如何檢測?

long a = 2 * Long.MAX_VALUE; 
System.out.println("long.max * smth > long.max... or is it? a=" + a); 

這讓我-2,而我希望它拋出一個NumberFormatException ...

有使這項工作的一個簡單的方法?因爲我有一些代碼可以在嵌套的IF塊中進行乘法運算,或者在循環中進行加法運算,所以我不願意爲每個IF或循環內部添加更多的IF。

編輯:哦,好像是從另一個問題,這個答案是最適合我的需要:https://stackoverflow.com/a/9057367/540394
我不想做裝箱/拆箱,因爲它增加unnecassary開銷,這種方式是非常總之,這對我來說是一個巨大的優勢。我只寫兩個簡短的函數來完成這些檢查並返回最小或最大長度。

EDIT2:這裏是根據我聯繫上面的答案限長到它的最小值/最大值功能:

/** 
* @param a : one of the two numbers added/multiplied 
* @param b : the other of the two numbers 
* @param c : the result of the addition/multiplication 
* @return the minimum or maximum value of a long integer if addition/multiplication of a and b is less than Long.MIN_VALUE or more than Long.MAX_VALUE 
*/ 
public static long limitLong(long a, long b, long c) 
{ 
    return (((a > 0) && (b > 0) && (c <= 0)) 
     ? Long.MAX_VALUE 
     : (((a < 0) && (b < 0) && (c >= 0)) ? Long.MIN_VALUE : c)); 
} 

告訴我,如果你認爲這是錯誤的。

+0

+1。應該有一些允許整數溢出檢測的庫。 – Thilo

+0

或者特殊塊(類似finally?),它可以幫助開發人員爲所有在其中執行的數學代碼啓用溢出錯誤行爲。我相信C#有一個。編輯:找到它,[在C#中選中和未選中的塊](http://msdn.microsoft.com/zh-cn/library/a569z7k8.aspx)。 –

+0

那麼,C#似乎拋出溢出錯誤(我非常喜歡沉默和錯誤的結果,對我來說沒有意義)... – jurchiks

回答

4

如果您不能確定結果會少於9萬億億,我會使用doubleBigInteger獲取錯誤對您無能爲力,因爲您仍然需要知道該怎麼辦。

通過驗證輸入以確保它們處於範圍內,並且如果結果的範圍大於long,可以使用可處理此類型的類型,這樣更好地避免首先出現錯誤。

隨着BigInteger的,你可以做

BigInteger a = BigInteger.valueOf(2).multiply(BigInteger.valueOf(Long.MAX_VALUE)); 
long l = a.longValue(); 
if (a.compareTo(BigInteger.valueOf(l)) == 0) { 
    // ok 
} else { 
    // error 
} 

雙,你可以做

double d = 2.0 * Long.MAX_VALUE; 
long l = (long) Math.max(Long.MIN_VALUE, Math.min(Long.MAX_VALUE, d)); 
// or as a helper method. 
long l = boundedCast(d); 

注意:在使用double,而不是長期可導致一些精度損失。

我寧願避免首先需要一個錯誤塊。

+1

事情是,如果超過它,我需要將其修剪爲「長」。也許這有幫助?在我的情況下獲得一個錯誤會有很大幫助;我可以將整個代碼放在try/catch塊中,如果發生錯誤,請將該值設置爲Long.MAX_VALUE,因爲這是我所需要的。 – jurchiks

+0

如果超過了很長時間,則無法修剪。你所能做的最好的就是使它成爲'Long.MAX_VALUE',這不是一個好的解決方案。 –

+3

@PeterLawrey我認爲將其限制爲「Long.MAX_VALUE」是OP的意思是*將其修剪爲「long」*。 – brimborium

2

超出long long的最大值不會引發異常,而是會返回。如果你這樣做:

Long.MAX_VALUE + 1

你會發現結果是等於Long.MIN_VALUE。

如果你想讓它拋出一個異常,檢查它是否達到了最大值,並拋出異常

[編輯]

您還可以使用Guava庫,以檢查是否存在溢出,當你總結兩個長期;

long c = LongMath.checkedAdd(a, b); 

當總結兩個長整數時發生溢出時會引發異常。

你可以找到javadoc的here

+2

「簡單地做一個檢查是否達到最大值」 - 你怎麼想的?我不想自己拋出異常,我不應該,確切地說。 – jurchiks

+0

你也可以試試這個:long c = LongMath.checkedAdd(a,b);如果在總結2個多頭時出現溢出,則會引發異常 –

+1

@DanielA。也許你應該補充說,你需要[番石榴庫](http://code.google.com/p/guava-libraries/)。 – Baz

-1

Long值超過MAX_VALUE不拋出任何異常。您需要手動檢查並處理這種情況。

儘管@PeterLawrey建議您應該考慮使用doubleBigInteger

+0

你怎麼用雙重做這個? BigInteger示例已發佈,但是雙倍...將Long.MAX_VALUE的值賦值爲double並打印出來給出了'9.223372036854776E18'。 – jurchiks