我正在开发一个程序,用于比较大整数分解的不同算法。我在比较中包括的算法之一是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 ,这是不正确的,因为 6194235479 * 2984853201 = 18488883597240918279 。我认为我得到了这个结果,因为在算法的某个地方,我得到了一个数字变得太大了很长时间或者类似的东西,所以算法因此而变得有些混乱。我添加了一张支票,它计算了两个因子的乘积,并与输入值进行了比较,这样如果分解出错,我会收到警报:
long x,y;
x = factors.get(0);
y = factors.get(1);
if(x*y!=n)
System.out.println("Faulty factorization.");
有趣的是,检查结果为真,我没有得到警报。我试着打印乘法的结果,这实际上导致了输入值。所以我的问题是为什么我的程序表现得像这样,我能做些什么呢?
答案 0 :(得分:2)
看起来long
某处有溢出,因为long有64位且
42139523531366663 + 2^64 = 18488883597240918279
对于足够大的数字,您可能需要切换到使用BigInteger
。
答案 1 :(得分:0)
是否因为在大数字倍增时出现错误?
这可能是一个有效的理由。这使得程序认为它的分解是正确的,但是当你在不使用程序的情况下实际乘以数字时,就会发现错误。