2

I wrote a program to calculate the multiplication of odd numbers between 1 and 100. So why does changing the data type give me a whole different output? Why is the output a negative number when I use int? Additionally, the other results seem weird. Code:

long total = 1L;
for (int i = 1; i <= 100; i++) {
    if (i % 2 != 0) {
        total *= i;
    }
}
System.out.println(total);

The output in different cases :

5196472710489536419 (if total is long)

-373459037 (if total is int)

2.7253921397507295E78 (if total is double)

Infinity (if total is float)

Mureinik
  • 297,002
  • 52
  • 306
  • 350
  • 1
    You might want to check other questions like https://stackoverflow.com/questions/5121698/java-sum-2-negative-numbers – Progman Dec 05 '21 at 12:58
  • 2
    Also, you might want to add a `System.out.println(total);` inside the `for` loop to see how the value is changing when the `for` loop is executing. – Progman Dec 05 '21 at 13:01
  • Does this answer your question? [Overflow occurs with multiplication](https://stackoverflow.com/questions/30606365/overflow-occurs-with-multiplication) – Nowhere Man Dec 05 '21 at 14:39
  • @AlexRudenko yeah it answered a lot but I still don't understand the difference of outputs when using double and long. I think both of them should give the same output – Qusay Abu Auda Dec 05 '21 at 14:50
  • 2
    @QusayAbuAuda The actual result for `total` is `2725392139750729502980713245400918633290796330545803413734328823443106201171875`, but the type `long` has an upper limit of `9223372036854775807`, so the result cannot be stored in a `long` typed variable. – Progman Dec 05 '21 at 15:04
  • 1
    @QusayAbuAuda The result cannot be saved in a `double` typed variable either, as double has a precision of ~15 digits, but this number have ~78 digits. The value in a `double` type variable will not be precise to hold that value. – Progman Dec 05 '21 at 15:07

1 Answers1

5

With different datatypes, the result would overflow in different ways. The result when using a double looks correct, although you're probably losing a lot of precision there. If you want to properly multiply an integer of arbitrary size, you should probably use a BigInteger:

BigInteger total = BigInteger.ONE;
for (int i = 1; i <= 100; i++) {
    if (i % 2 != 0) {
        total = total.multiply(BigInteger.valueOf(i));
    }
}
System.out.println(total);

Side note: instead of iterating all the ints between 1 and 100 and checking if they are odd or not, you could start with 1 and then increment each iteration by 2 instead of 1:

BigInteger total = BigInteger.ONE;
for (int i = 1; i < 100; i+=2) {
    total = total.multiply(BigInteger.valueOf(i));
}
System.out.println(total);
Mureinik
  • 297,002
  • 52
  • 306
  • 350