大きな整数の因数分解のさまざまなアルゴリズムを比較するプログラムに取り組んでいます。比較に含めているアルゴリズムの 1 つは、Fermats 因数分解法です。このアルゴリズムは、小さな数では問題なく機能しているように見えますが、大きな数になると奇妙な結果が得られます。
これが私のコードです:
public void fermat(long n)
{
ArrayList<Long> factors = new ArrayList<Long>();
a = (long)Math.ceil(Math.sqrt(n));
b = a*a - n;
b_root = (long)(Math.sqrt(b)+0.5);
while(b_root*b_root != b)
{
a++;
b = a*a - n;
b_root = (long)(Math.sqrt(b)+0.5);
}
factors.add(a-b_root);
factors.add(a+b_root);
}
ここで、42139523531366663 を因数分解しようとすると、結果の因数6194235479と2984853201が得られます。この結果が得られたのは、アルゴリズムのどこかで数字が長くなりすぎたり、似たようなものになるポイントに到達したためだと考えました。そのため、アルゴリズムが少し混乱しました。2 つの因数の積を計算し、入力値と比較するチェックを追加して、因数分解に問題がある場合にアラートを受け取るようにしました。
long x,y;
x = factors.get(0);
y = factors.get(1);
if(x*y!=n)
System.out.println("Faulty factorization.");
興味深いことに、チェックは true として渡され、アラートは表示されませんでした。乗算の結果を印刷してみましたが、これが実際に入力値になりました。私の質問は、なぜ私のプログラムがこのように動作するのか、それに対して何ができるのかということです。