2010-05-14 203 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

相关问题