数値が与えられた場合、それがラマヌジャン数であるかどうかをテストします (このコースでは、2 つの異なる方法で 2 つの立方体の合計として定義されています)。n^(1/3) 時間で実行する必要があります。
私のコードは動作しています - 時々。テスト値が 2^63 -1 に近づくと、ランダム エラーが発生します。
奇妙なことに、別のバグを修正するためにカウンターの開始値を変更する前に、その範囲の数値についてこのテストに合格していました。これがなぜなのか誰か教えてもらえますか?
a^3 の値を作成するために for ループを設定しました。
次に、b=(na^3)^(1/3) の値を設定します。
次に、b が整数かどうかをテストします。もしそうなら、ループを壊してください。
コードを機能させるためにここに if テストを挿入しましたが、これが必要な理由はわかりません。それがこの質問の要点です。この if ステートメントは、n=2^63 より上と下の値に対して 2 つの異なる for ループを設定します。
n < 2^63 の 2 番目のループは、c=a+1 で始まるため、重複しません。最初のものと同じです。
n > 2^63 の 2 番目のループは、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));
}
}
大きい数値と小さい数値を区別する必要がある理由についての洞察はありますか?