【问题标题】:How to fix "largeNumber^5+1 = largeNumber^5" in Java [duplicate]如何在 Java 中修复“largeNumber^5+1 = largeNumber^5”[重复]
【发布时间】:2016-06-26 17:38:20
【问题描述】:

我正在搜索 a、b 和 c,使得 a^5+b^5 = c^5。我的程序产生 2000^5+1= 2000^5。为什么会发生这种情况以及如何解决?

public class Euler {

     public static void main(String[] args) {
        long i=0;
        int power = 5;
        int a1 = 1; 
        int a2 = 2000;

        boolean isSolved = false;
        long sumOfPowers = 0;
        double root = 0;
        long roundDown = 0;
        long roundDown2Power = 0;

            sumOfPowers = (long) (Math.pow(a1, power) + Math.pow(a2, power));
            root = Math.pow(sumOfPowers, 1.0/power);

            roundDown = (long) root;
            roundDown2Power = (long)Math.pow(roundDown, power);

            if (sumOfPowers == roundDown2Power) {
                isSolved = true;
                System.out.println(isSolved + " " + a1 + "^" + power + " + " + a2 + "^" + power + " + "  + "^" + power +  " = " + roundDown + "^" + power );
            }
        }
    }

我正在寻找欧拉猜想的反例。使用这种方法An error searching for a counterexample to Euler's conjecture我成功获得了五次幂 27^5 + 84^5 + 110^5 + 133^5 = 144^5 (Lander & Parkin, 1966),需要 6 秒。我试图得到 5800^4 + 217519^4 + 414560^4 = 422481^4(Roger Frye,1988 年),但是在测试这个模块时,我发现我的程序产生了 2000^5+1=2000^5。这是个问题。

【问题讨论】:

  • 当然,我知道。我试图找到en.wikipedia.org/wiki/Euler%27s_sum_of_powers_conjecture 的反例,我让它适用于 n=5,但由于舍入错误20k^4+1=20k^4,我无法使其适用于 n=4。
  • 原始类型可以表示的值范围有限,在浮点/双精度的情况下,可以表示的值的精度也受到限制(对于大于 n>2^52 的整数值表达式 n==n+1 变为 true)。您将需要切换到使用任意精度类型,例如BigInteger 来克服这些限制(但预计性能会显着下降)。
  • BigInteger 没有开箱即用的计算根的方法。

标签: java bignum


【解决方案1】:

您的问题是 long 和 double 类型可以做什么(并且被精确定义为做什么)与您对方程的纯数学视图不匹配。

原始类型可以表示的值范围有限。那是什么绊倒你的计算。 long 可以表示 Long.MAX_VALUE (2^63-1) 和 Long.MIN_VALUE -(2^63) 范围内的值。 double 类型可以表示更大的范围但以准确性为代价。表示为双精度的整数只能精确表示到 2^52,高于最低有效(二进制)数字被丢弃。这都是因为这些类型在内存中具有 64 位的固定大小,并且不可能在这些位中表示超过 2^64 个状态。

解决您的问题的方法不是使用这些类型,而是使用任意精度类型,该类型可以准确地表示大数而无需截断或舍入。为此目的有 BigInteger 和 BigDecimal 类。请注意,BigDecimal 仍然会四舍五入(例如,您不能用它表示 1/3),只有您可以选择在哪里进行四舍五入。

这些也是对象类型,这意味着您不能编写方程式,您必须调用它们的方法才能对它们执行操作。可用的操作也有些受限,需要重新安排一些问题才能解决。

编辑:对于 long 和 double 类型的行为没有什么 java 特定的,在为您提供相同类型的 any 语言中,您会遇到完全相同的问题。双重行为是指定的标准 (IEEE-754),长属性由二进制补码规则(及其 64 位大小)决定。

【讨论】:

  • 我是从 John 的评论中得知的。如何使用 BigInteger?我试过BigInteger a = 1;,但它没有编译。
  • @sixtytrees 正如我所写,您必须调用他们的方法,而不是编写方程式,有记录它的 javadoc。如果这还不够,一个简单的搜索会找到像这样的示例代码:compsci.ca/v3/viewtopic.php?t=13193
【解决方案2】:

您应该尝试在 Java 中使用 BigInteger 库。

【讨论】:

  • 这没有回答“为什么”。请详细说明。 (不是反对者)
  • 回到正轨@John - 你的答案质量很低。由于您直到现在才解决这种情况,所以您现在也得到了我的反对。只是喊出一个流行词可能对 OP 有帮助,但这仍然会留下一个不好的答案。包括一些解释 OP 最初做错了什么以及如何通过使用 BigInteger 来改变这种情况。
  • @luk2302 你为什么不自己写一个好的答案呢?只是举个例子?
  • @sixtytrees 因为那不是我来这里的目的——我来这里是为了缓和!我不是想获得积分或发布答案。
猜你喜欢
  • 2018-07-05
  • 1970-01-01
  • 1970-01-01
  • 2015-08-09
  • 1970-01-01
  • 1970-01-01
  • 2014-03-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多