【问题标题】:Project Euler #6 Two codes, different answers ONLY for big inputs. Why?Project Euler #6 两个代码,仅针对大输入的不同答案。为什么?
【发布时间】:2014-01-27 08:45:07
【问题描述】:

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

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

12 + 22 + ... + 102 = 385

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

(1 + 2 + ... + 10)2 = 552 = 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

【问题讨论】:

  • 不要使用Math.pow(sum, 2),只使用sum * sum
  • 您的解决方案似乎是必要的?请参阅下面我对彼得的评论..

标签: java truncated


【解决方案1】:

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

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

在 Java 中,当整数运算的结果不适合 int 变量时,
你应该使用 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);
    }

}

【讨论】:

  • @assylias 没问题。 ; )
  • 谢谢彼得。好消息是我的两个代码现在都给出了相同的输出: Sum Squared = 6553755928790448384 Sum Of Squares = 333338333350000 但是,上面由 Khaled 提供的代码给出了不同的答案: 25000500002500000000 333338333350000 这看起来更好,因为它与较低的答案相同数字 (100,1000, 10000) 只有更多的零....
  • 他的回答是可以的。我的代码中有溢出。 Java 中最大的 long 值是:9223372036854775807。25000500002500000000 高于该数字。我现在将更正我的代码。他的代码中有一些多余的部分,但他的代码在逻辑上是可以的。
  • 我可以整天待在这里,为什么还要浪费时间在大学里!
  • 不,不,我们在大学里学到了更多;)所以你也应该去那里。
猜你喜欢
  • 2023-03-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-29
  • 1970-01-01
  • 2013-08-11
  • 1970-01-01
相关资源
最近更新 更多