3

Here are two codes for solving problem 6 in project euler: Why do they give similar answers until I make the number larger? (100,000)

The sum of the squares of the first ten natural numbers is,

12 + 22 + ... + 102 = 385

The square of the sum of the first ten natural numbers is,

(1 + 2 + ... + 10)2 = 552 = 3025

Hence the difference between the sum of the squares of the first ten natural numbers and the square of the sum is 3025 − 385 = 2640.

Find the difference between the sum of the squares of the first one hundred natural numbers and the square of the sum.

Code 1:

public class Problem_Six_V2 {

public static void main(String[] args) {

    long limit = 100000;
    long sum = (limit * (limit + 1)) / 2;
    long sumOfSqr = (long)((((2*limit)*limit)+((2*limit)*1)+(1*limit)+(1*1))*limit)/6;
    System.out.println(Math.pow(sum, 2) +" "+ sumOfSqr);
    System.out.println(Math.pow(sum, 2) - sumOfSqr);
}

}

^^^ Outputs = 2.500016666416665E19

Here's code two:

public class Problem_Six {

public static void main(String[] args) {

    long sum = 0;
    long sumSqr = 0;
    long sumOfSqr = 0;

    for(long i = 1; i <= 100000; i++){
        sum += i;
        sumOfSqr += Math.pow(i,2);
    }
    sumSqr = (long) Math.pow(sum, 2);
    System.out.println(sumSqr +" "+ sumOfSqr);
    System.out.println(sumSqr - sumOfSqr);
}
}

^^ Outputs = 9223038698521425807

I guess it's something to two with the types being used, but they seem similar in both codes..hmm

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
COOLBEANS
  • 729
  • 3
  • 13
  • 31

1 Answers1

6

Math.pow(i,2) accepts doubles as parameters. Doubles are not 100% precise,
you lose precision. Stick to operations on int/long only. The answer is pretty small
and fits even into an int.

Not sure why you use 100000 as your limit, problem 6 has 100 as a limit.

In Java when results of integer arithmetic don't fit into int variables,
you should use long, when they don't fit even into long variables, you
should use BigInteger.

But avoid doubles, they are not precise for such kinds of tasks.

Here is your program corrected.

import java.math.BigInteger;

public class Problem_Six {

    public static void main(String[] args) {

        BigInteger sum = BigInteger.ZERO;
        BigInteger sumSqr = BigInteger.ZERO;
        BigInteger sumOfSqr = BigInteger.ZERO;

        for (long i = 1; i <= 100000; i++) {
            sum = sum.add(BigInteger.valueOf(i));
            sumOfSqr = sumOfSqr.add(BigInteger.valueOf(i * i));             
        }

        sumSqr = sum.multiply(sum);
        System.out.println(sumSqr + " " + sumOfSqr);
        System.out.println(sumSqr.subtract(sumOfSqr).toString());

        // System.out.println(Long.MAX_VALUE);
    }

}
peter.petrov
  • 38,363
  • 16
  • 94
  • 159
  • Thanks Peter. The good news is that both my two codes now gives the same output: Sum Squared = 6553755928790448384 Sum Of Squares = 333338333350000 However, the code provided above by Khaled gives a different answer: 25000500002500000000 333338333350000 This looks better because it's the same answer as with lower numbers (100,1000, 10000) only with more zeros.... – COOLBEANS Jan 27 '14 at 13:40
  • 1
    His answer is OK. I had an overflow in my code. The biggest long value in Java is: 9223372036854775807. 25000500002500000000 is above that number. I will correct my code now. He has some superfluous parts in his code but his code is logically OK. – peter.petrov Jan 27 '14 at 14:02
  • Why do I waste time in College when I could stay here all day! – COOLBEANS Jan 27 '14 at 14:04
  • No, no, we've learned more of that in college ;) So you should drop by there too. – peter.petrov Jan 27 '14 at 14:04