2010-05-14 378 views
10

對於一個小項目(問題10項目歐拉),我試圖總結所有低於200萬的素數。所以我用了一個蠻力方法,並且從0到2'000'000進行迭代,並檢查數字是否爲素數。如果它是我加上的總和:爲什麼Java不能告訴我什麼時候我不能使用Integer?

private int sum = 0; 

private void calculate() { 
    for (int i = 0; i < 2000000; i++) { 
     if (i.isPrime()) { 
     sum = sum + i; 
     } 
    } 
    sysout(sum) 
} 

這個計算的結果是1179908154,但這是不正確的。所以我改變了int到BigInteger,現在我得到了正確的總和142913828922.顯然int的範圍溢出了。但爲什麼Java不能告訴我這些? (例如,例外)

+3

順便說一句,BigInteger的是矯枉過正和長 – DJClayworth 2010-05-14 13:38:13

+0

爲什麼你不使用Eratosthenes篩而不是蠻力強迫它? – CoolBeans 2010-05-14 14:21:29

+1

@DJClayworth:虐待嘗試 @CoolBeans:暴力強度足夠快,只需要幾分之一秒 – RoflcoptrException 2010-05-14 14:24:23

回答

13

因爲可以想象,您可能希望它以傳統的Integer方式運行。例外是保留給那些肯定和不可撤銷的錯誤的東西。

ETA:從語言規範:

「內置的整數經營者都不 表明任何 方式溢或下溢唯一的數字運算符 可以拋出一個異常(§。 11)是 整數除法運算符/(§15.17.2) 和整數餘數運算符%(%) (§15.17.3),如果右邊的 操作數爲零,則拋出 ArithmeticException。

http://java.sun.com/docs/books/jls/second_edition/html/typesValues.doc.html

+0

那麼我應該總是測試之前添加一個數字,如果超過範圍? – RoflcoptrException 2010-05-14 12:58:59

+4

如果你知道你的號碼可以很大,你應該使用'更大'的類來處理它。 – 2010-05-14 13:02:03

+0

我同意菲利普。如果您需要保證x + 1> x的值高於整數範圍,請使用BigInteger。如果因爲其他原因使用int,整數應該是正確的。 – 2010-05-14 13:10:28

3

再說什麼吉姆說,檢查如溢出會增加的性能損失與整數做過計算,這將使該做大量的計算速度慢了很多的程序條件。

+2

而_that_就是這樣做的真正原因。這也是爲什麼我們有原始人! – naiad 2010-05-14 14:03:39

+0

@Vuntic我不認爲這就是爲什麼我們有原語的真正原因 - 在其他語言(例如Scala)中,當您使用Int類時,編譯器足夠聰明,可以使用本地整數。換句話說,如果Java編譯器變得更聰明,那麼原語數據類型就不需要在編程語言中暴露出來。 – Jesper 2010-05-14 14:06:05

+0

1)您正在比較相隔15年以上的兩種語言。 2)Java編譯器不允許「聰明」並且用另一種類型替換一種類型......除非JLS對此進行處罰。 (明確賦值的規則是Java編譯器不被允許爲「智能」的另一個例子。) – 2010-05-14 14:27:29

0

意識到Integer.MAX_VALUE的始終是有用的:)

1

另一個原因是,你可以做到這一點很容易和快速地檢查自己。

if (sum+i < sum) { 
    throw new AritchmeticException(); 
} 

應該很好地做這個訣竅,因爲你知道我總是積極的並且比Integer.MAX_VALUE少。

0

因爲我們的專業重視表現超過正確性。 ;(

使用的BigInteger默認情況下,只有推理是否接受,使用長或INT如果性能是一個現實的問題,將有助於避免此類問題

+0

實際上,因爲Java語言設計者希望給程序員以正確性來評估性能的選項。 – DJClayworth 2010-05-18 18:31:31

相關問題