3

以下是解决项目 euler 中问题 6 的两个代码: 为什么在我将数字变大之前它们给出的答案相似?(100,000)

前十个自然数的平方和是,

1 2 + 2 2 + ... + 10 2 = 385

前十个自然数之和的平方是,

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

因此,前十个自然数的平方和与和的平方之差为 3025 - 385 = 2640。

求前一百个自然数的平方和与和的平方之间的差。

代码 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);
}

}

^^^ 输出 = 2.500016666416665E19

下面是代码二:

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);
}
}

^^ 输出 = 9223038698521425807

我想这与所使用的类型有关,但它们在两个代码中似乎相似..hmm

4

1 回答 1

6

Math.pow(i,2)接受双打作为参数。双打不是 100% 精确的,
你会失去精确度。坚持只对 int/long 进行操作。答案非常小
,甚至适合 int。

不知道为什么你使用 100000 作为你的限制,问题 6 有 100 作为限制。

在 Java 中,当整数运算的结果不适合 int 变量时,
您应该使用 long,当它们甚至不适合 long 变量时,您
应该使用 BigInteger。

但是避免双打,它们对于这类任务并不精确。

这是您的程序更正。

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);
    }

}
于 2014-01-27T08:52:30.803 回答