使用BigInteger的唐津乘法 [英] Karatsuba Multiplication using BigInteger

查看:110
本文介绍了使用BigInteger的唐津乘法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我首先用long编写了Karatsuba算法的代码。我认为它运作良好。使用相同的逻辑,我将代码转换为BigInteger,但由于某些原因,它给出了StackOverflowError。

I first wrote a code for Karatsuba algorithm using long. It works perfectly I think. Using the same logic I converted the code to BigInteger but for some reasons its giving StackOverflowError.

我不知道为什么。请帮忙。

I cant figure out why. Please help.

编辑1:长时间的代码也有逻辑上的缺陷。我不知道该怎么办。

The code for long also has a logical flaw. I am not sure what.

EDIT2:现在可以长时间使用的代码了。我错误地将%运算符切换为 /。

The code for long works now. I switched a "%" operator with "/" by mistake.

EDIT3:现在一切顺利。我将.xor更改为.pow,将==更改为.equals,并修复了return语句中的某些括号问题。谢谢大家的帮助!

All good now. I changed .xor to .pow and == to .equals and fixed some bracket issues in the return statement. Thank you everyone for the help!

这是正确的代码:

public static BigInteger karatsuba3(BigInteger i, BigInteger j){
    if (i.compareTo(Ten) == -1 || j.compareTo(Ten) == -1)
        return i.multiply(j);
    String length = getLength(i.max(j));
    BigInteger n = new BigInteger(length);
    if (n.mod(Two).equals(One))
        n = n.add(One);

    BigInteger a = i.divide(Ten.pow(n.divide(Two).intValue()));
    BigInteger b = i.mod(Ten.pow(n.divide(Two).intValue()));
    BigInteger c = j.divide(Ten.pow(n.divide(Two).intValue()));
    BigInteger d = j.mod(Ten.pow(n.divide(Two).intValue()));

    BigInteger first = karatsuba3(a,c);
    BigInteger second = karatsuba3(b,d);
    BigInteger third = karatsuba3(a.add(b),c.add(d));

    return ((first.multiply(Ten.pow(n.intValue()))).add ((((third.subtract(first)).subtract( second))).multiply(Ten.pow(n.divide((new BigInteger("2"))).intValue()))).add(second));
}

Karatsuba,长代码:

Karatsuba with long code:

public static long karatsuba1(long i, long j){
    if (i < 10 || j < 10) 
        return i*j;
    double n = getLength(Math.max(i,j));
    if (n%2 == 1)
        n++;
    long a = (long) (i/Math.pow(10,(n/2)));
    long b = (long) (i%Math.pow(10,(n/2)));
    long c = (long) (j/Math.pow(10,(n/2)));
    long d = (long) (j%Math.pow(10,(n/2)));

    long first = karatsuba1(a, c);
    long second = karatsuba1(b, d);
    long third = karatsuba1(a + b, c + d);

    return ((long) ((first * Math.pow(10, n)) + ((third - first - second) * Math.pow(10, (n/2))) + second));
}

public static int getLength( long a){
    String b = Long.toString(a);
    return b.length();
}

Karatsuba的BigInteger代码:

Karatsuba with BigInteger code:

public static BigInteger karatsuba3(BigInteger i, BigInteger j){
    BigInteger Ten = new BigInteger("10");
    if (i.compareTo(Ten) == -1 || j.compareTo(Ten) == -1)
        return i.multiply(j);
    String length = getLength(i.max(j));
    BigInteger n = new BigInteger(length);
    if (n.mod(new BigInteger("2")) == new BigInteger("1"))
        n.add(new BigInteger ("1"));

    BigInteger a = i.divide(Ten.xor(n.divide((new BigInteger("2")))));
    BigInteger b = i.mod(Ten.xor(n.divide((new BigInteger("2")))));
    BigInteger c = j.divide(Ten.xor(n.divide((new BigInteger("2")))));
    BigInteger d = j.mod(Ten.xor(n.divide((new BigInteger("2")))));

    BigInteger first = karatsuba3(a,c);
    BigInteger second = karatsuba3(b,d);
    BigInteger third = karatsuba3(a.add(b),c.add(d));

    return ((first.multiply(Ten.xor(n))).add (((third.subtract(first).subtract( second)))).multiply(Ten.xor(n.divide((new BigInteger("2"))))).add(second));
}

public static String getLength( BigInteger a){
    String b = a.toString();
    return Integer.toString(b.length());
}


推荐答案

在第一个代码段中,这行对我来说似乎是错的:

In the first snippet, this line looks wrong to me:

long d = (long) (j/Math.pow(10,(n/2)));

所以现在您有 c = d
可能要:

so right now you have c = d probably you want:

long d = (long) (j%Math.pow(10,(n/2)));

这篇关于使用BigInteger的唐津乘法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆