Java实现大数乘法_Java实现大整数乘法

请设计一个有效的算法,可以进行两个n位大整数的乘法运算

1 最暴力的方法:O(n^2)

2 我们采用分而治之的思想

将X和Y按如下方法分成两部分

afdc81ec69010135cd5cc607df3f4b68.png

1ea7ce3ab680a2e37c394276b19d86ef.png

那么

X = A*10^(n/2) + B

Y = C*10^(n/2) + D

X*Y = (A*10^(n/2) + B)*( C*10^(n/2) + D)

= A*C*10^n + A*D*10^(n/2) + B*C*10^(n/2) + B*D

复杂度分析

512ec34ff8331f27df894ce3db1215fc.png

为了降低时间复杂度,必须减少乘法的次数

上式可改写为

X*Y = (A*10^(n/2) + B)*( C*10^(n/2) + D)

= A*C*10^n + A*D*10^(n/2) + B*C*10^(n/2) + B*D

= A*C*10^n + ((A+B)(C+D) – A*C – B*D)*10*(n/2) + B*D

或者

= A*C*10^n + ((A-B)(D-C) + A*C + B*D)*10*(n/2) + B*D

复杂度分析

4e34a2b93796b32a9c17b1981913f54e.png

Java代码

package powernumber;

/**

* 大整数相乘

* @author Dudu

* @date 2018-11-10

*/

public class BigDataRide {

public static int sign(long a) {

return a < 0 ? -1 : 1;

}

public static double bigdataride(long x,long y,int n) {

x = Math.abs(x);

y = Math.abs(y);

if (n == 1) {

return x * y;

}

else {

if (n%2==1) {

n = n - 1; //对奇数的操作

}

long a = x / Math.round(Math.pow( 10 , (n / 2)));

long b = x - a * Math.round(Math.pow( 10 , (n / 2)));

long c = y / Math.round(Math.pow( 10 , (n / 2)));

long d = y - c * Math.round(Math.pow( 10 , (n / 2)));

double ac = bigdataride(a,c,n/2);//递归计算a*c

double bd = bigdataride(b,d,n/2);//计算b*d

long aJb = a + b;

long cJd = c + d;

double abcd = bigdataride(aJb,cJd,n/2);

return (ac*Math.pow(10,n) + (abcd - ac - bd)*Math.pow(10,n/2) +bd);

}

}

public static void main(String[] args) {

// 大整数相乘

long x = 12234L;

long y = 45243L;

String sx = String.valueOf(x);

int n = sx.length();

long sig = sign(x)*sign(y);

double s = bigdataride(x,y,n);

System.out.println("大数相乘的计算结果为:"+s*sig);

}

}

输出的结果为:5.53502862E8

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值