Java n是Ramanujan数--为什么在2^63附近的值中会出现错误?

Java n是Ramanujan数--为什么在2^63附近的值中会出现错误?,java,largenumber,hardy-ramanujan,Java,Largenumber,Hardy Ramanujan,给定一个数,测试它是否是一个Ramanujan数,在我们的课程中定义为两个不同方式的立方体之和。它必须在n^1/3时间内运行 我的代码有时会起作用。随着测试值接近2^63-1,我得到一些随机错误 奇怪的是,在更改计数器的起始值以修复不同的错误之前,我通过了该范围内数字的测试。有人能告诉我为什么会这样吗 我设置了for循环以创建^3的值 然后我设置b=n-a^3^1/3的值 然后我测试b,看它是否是一个整数。如果是这样,打破循环 在这里插入了一个if测试以使代码正常工作,尽管我不知道为什么需要这样

给定一个数,测试它是否是一个Ramanujan数,在我们的课程中定义为两个不同方式的立方体之和。它必须在n^1/3时间内运行

我的代码有时会起作用。随着测试值接近2^63-1,我得到一些随机错误

奇怪的是,在更改计数器的起始值以修复不同的错误之前,我通过了该范围内数字的测试。有人能告诉我为什么会这样吗

我设置了for循环以创建^3的值

然后我设置b=n-a^3^1/3的值

然后我测试b,看它是否是一个整数。如果是这样,打破循环

在这里插入了一个if测试以使代码正常工作,尽管我不知道为什么需要这样做,这就是这个问题的要点。此if语句为n=2^63以上和以下的值设置两个不同的for循环

对于n<2^63的第二个循环,从c=a+1开始,所以我不重复。和第一个一样

n>2^63的第二个循环以c=a开始

为什么这会有不同?为什么相同的代码不能用于更小和更大的数字

抱歉,我的代码太幼稚了,我才刚刚开始,很多函数在我的课程中都是禁止使用的。例如,我不能使用floor,也不能为它编写自己的函数

public class Ramanujan {
public static boolean isRamanujan(long n) {
    if (n <= 0) return false;
    long a3 = 0;
    long c3 = 0;
    double b = 0;
    double d = 0;
    for (int a = 1; a < n; a++) {
        a3 = (long) a * a * a;
        if (a3 > n) break;
        b = Math.cbrt(n - a3);
        if (b == (int) b) break;
    }
    if (n > Math.pow(2, 62)) {
        for (int c = (int) Math.cbrt(a3); c < n; c++) {
            c3 = (long) c * c * c;
            if (c3 > n) break;
            d = Math.cbrt(n - c3);
            if (d == (int) d) break;
        }
    }
    else {
        for (int c = (int) Math.cbrt(a3) + 1; c < n; c++) {
            c3 = (long) c * c * c;
            if (c3 > n) break;
            d = Math.cbrt(n - c3);
            if (d == (int) d) break;
        }
    }
    if (a3 + (long) b * b * b == c3 + (long) d * d * d && b * b * b != c3) 
return true;
    return false;
}

public static void main(String[] args) {
    long n = Long.parseLong(args[0]);
    StdOut.println(isRamanujan(n));

}
}

关于我为什么需要区分大数字和小数字,你有什么见解吗?

当n超过long可以容纳的值时,你会得到奇怪的结果,即Math.pow2,63==long.MAX\u值。此时,n将经历一个数字溢出

final long l = Long.MAX_VALUE; // == 2^63
System.out.println(l); // 9223372036854775807
System.out.println(l + 1); // -9223372036854775808

在Java中,long可以容纳的最大值是2^63-1 long.MAX\u值。 你为什么要计算数学?如果a3=a*a*a,那么你已经知道了 Math.cbrta3是

如果n>9223372036854774272,则代码中存在问题 9223372036854774273的Math.cbrt为2097152
如果你计算多维数据集,你会因为溢出而得到一个负数。

问题在于将int类型的变量a和c相乘来计算多维数据集。需要将每个被乘以的变量强制转换为long

final long l = Long.MAX_VALUE; // == 2^63
System.out.println(l); // 9223372036854775807
System.out.println(l + 1); // -9223372036854775808

例如,a3=长a*长a*长a

是的,但值刚好低于该阈值。针对该计划使用的测试为:测试13:检查Ramanujan编号接近2^63-1的isRamanujan 92232615649125250489*isRamanujan 9223278330318728221=>通过