如何在 Java 中修复 "largeNumber^5+1 = largeNumber^5"

How to fix "largeNumber^5+1 = largeNumber^5" in Java

我正在搜索满足 a^5+b^5 = c^5 的 a、b 和 c。我的程序产生 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 );
            }
        }
    }

我正在寻找欧拉猜想的反例。我用这个方法成功了五次方 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。这是个问题。

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

您的问题是 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),只有您可以 select 在何处舍入。

而且这些都是对象类型,这意味着你不能写方程,你必须调用它们的方法来对它们进行操作。可用的操作也有些有限,需要重新排列一些问题才能解决。

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