views:

245

answers:

5

For a small project (Problem 10 Project Euler) i tried to sum up all prime numbers below 2 millions. So I used a brute force method and iterated from 0 to 2'000'000 and checked if the number is a prime. If it is I added it to the sum:

private int sum = 0;

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

The result of this calculation is 1179908154, but this is incorrect. So i changed int to BigInteger and now i get the correct sum 142913828922. Obviously the range of int was overflowed. But why can't Java tell me that? (e.g. by an exception)

+13  A: 

Because it's conceivable that you might want it to behave in the traditional Integer fashion. Exceptions are reserved for things that are definitely and irrevocably wrong.

ETA: From the language spec:

"The built-in integer operators do not indicate overflow or underflow in any way. The only numeric operators that can throw an exception (§11) are the integer divide operator / (§15.17.2) and the integer remainder operator % (§15.17.3), which throw an ArithmeticException if the right-hand operand is zero."

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

Jim Kiley
then i should always test before adding a number if rhe range is exceeded?
Roflcoptr
If you know you number can be big you should use a 'bigger' class to handle it.
Felipe Cypriano
I agree with Felipe. If you need a guarantee that x + 1 > x for values above Integer's range, use BigInteger. If you're using an int for another reason, Integer should be OK.
Jim Kiley
@Jim Kiley - or a `Long`/`long`, for numbers above Integer's range but definitely always within the range of longs (`Long.MAX_LONG` ~= 2^63), would be a more natural replacement. That's not to say that `BigInteger`s aren't useful, but they're a bit more specialised.
Andrzej Doyle
@Andrzej you are of course correct; in my defense, the coffee here is weak and so I wasn't fully awake when I wrote that.
Jim Kiley
`Because it's conceivable that you might want it to behave in the traditional Integer fashion.` It's conceivable that you'd want just about any of the convenience features to behave in the traditional methods (eg. overstepping array bounds). The reason we DON'T is that **making the common case the default is much more important than absolute power**.
BlueRaja - Danny Pflughoeft
+2  A: 

Besides what Jim says, checking for conditions such as overflow would add a performance penalty to any calculation done with integers, which would make programs that do a lot of calculations a lot slower.

Jesper
And _that_ is the real reason why it's done that way. It's also why we have primitives!
Vuntic
@Vuntic I don't think that's the real reason why we have primitives - in other languages (Scala for example) the compiler is smart enough to make use of native integers when you use for example the Int class. In other words, if the Java compiler would have been made smarter, primitive data types would not need to have been exposed in the programming language.
Jesper
@Jesper - 1) You are comparing 2 languages whose origins are 15+ years apart. 2) A Java compiler is not allowed to be "smart" and replace one type with another ... unless the JLS sanctions this. (The rules for definite assignment are another example where the Java compiler is not allowed to be "smart".)
Stephen C
A: 

Being aware of Integer.MAX_VALUE is always useful :)

LenW
+1  A: 

The other reason is that you can do this check yourself very easily and quickly.

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

should do the trick nicely, given that you know i is always positive and less than Integer.MAX_VALUE.

DJClayworth
A: 

Because our profession values performance over correctness. ;(

Using BigInteger by default, and only reasoning whether it is acceptable, to use long or int if performance is a real problem, would help to avoid such problems.

user unknown
Actually because the Java language designers want to give programmers the option to value performance over correctness.
DJClayworth