两个64位整数乘法

版权声明: https://blog.csdn.net/s0cket/article/details/85276422

 coursera斯坦福算法的编程题,用到的知识点:

1、BigInteger  
2、BigDecimal 
3、recursive integer multiplication and/or Karatsuba's algorithm 递归整数乘法或Karatsuba算法。

Karatsuba算法是对递归整数乘法的优化,可以将4次递归调用简化为3次。

public class Multiply_64 {

    public static void main(String[] args) {
        BigInteger bigInteger1 = new BigInteger("3141592653589793238462643383279502884197169399375105820974944592");
        System.out.println(bigInteger1);
        BigInteger bigInteger2 = new BigInteger("2718281828459045235360287471352662497757247093699959574966967627");

        Multiply_64 multiply_64 = new Multiply_64();
        System.out.println(multiply_64.m(bigInteger1, bigInteger2, 64));
    }

    private BigInteger m(BigInteger x, BigInteger y, int n) {
        BigInteger b1;
        BigInteger b3;
        b1 = new BigInteger(new BigDecimal(String.valueOf(Math.pow(10, (double) n))).setScale(0, BigDecimal.ROUND_HALF_UP).toPlainString());
        b3 = new BigInteger(new BigDecimal(String.valueOf(Math.pow(10, (double) n / 2))).setScale(0, BigDecimal.ROUND_HALF_UP).toPlainString());

//        System.out.println(Math.pow(10, (double) n / 2));
//        System.out.println(String.valueOf(Math.pow(10, (double) n / 2)));
        BigInteger a = x.divide(b3);
        System.out.println(a);
        BigInteger b = x.mod(b3);
        BigInteger c = y.divide(b3);
        BigInteger d = y.mod(b3);
//        System.out.println(Math.pow(10, (double) n / 2));

        if (n < 2) {
            return new BigInteger("0");
        } else if (n == 2) {

            BigInteger b2 = a.multiply(c);//a*c

            BigInteger b4 = (((a.add(b)).multiply(c.add(d))).subtract(a.multiply(c))).subtract(b.multiply(d));//(a + b) * (c + d) - a * c - b * d
            BigInteger b5 = b.multiply(d);//b*d
            return ((b1.multiply(b2)).add(b3.multiply(b4))).add(b5);//((long) Math.pow(10, (double) n)) * a * c + ((long) Math.pow(10, (double) n / 2)) * ((a + b) * (c + d) - a * c - b * d) + b * d;
        } else {
            BigInteger part1 = b1.multiply(m(a, c, n / 2));
            BigInteger part2 = b3.multiply(m(a, d, n / 2).add(m(b, c, n / 2)));
            BigInteger part3 = m(b, d, n / 2);
            return part1.add(part2.add(part3));
            //((long) Math.pow(10, (double) n)) * m(a, c, n / 2) + ((long) Math.pow(10, (double) n / 2)) * (m(a, d, n / 2) + m(b, c, n / 2)) + m(b, d, n / 2);
        }
    }
}

java.Math.BigInteger:

BigInteger b1 = new BigInteger("123");//输入类型为数字字符串
BigInteger b2 = new BigInteger("456");
b1.add(b2);//b1+b2,返回BigInteger对象
b1.substact(b2);//b1-b2
b1.mutiply(b2);
b1.divide(b2);

java.Math.BigDecimal:

需要对BigDecimal进行截断和四舍五入使用setScale():

 public static void main(String[] args)
    {
        BigDecimal a = new BigDecimal("4.5635");

        a = a.setScale(3, RoundingMode.HALF_UP);    //保留3位小数,且四舍五入
        System.out.println(a);
    }

本算法仍使用了分治算法,4次递归调用。尝试采用Karatsuba算法进行优化,但两个数的和的位数会发生变化,需要下一步解决。

猜你喜欢

转载自blog.csdn.net/s0cket/article/details/85276422