我是靠谱客的博主 贤惠烤鸡,最近开发中收集的这篇文章主要介绍自己动手写Java大整数《2》优化和乘法,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

在决定自己动手写Java下的大整数包后。

上周写了大整数的表示、绝对值的比较大小、取负值和加减法运算。

这次我看到别人的方法后改进了绝对值比较大小的代码,并且添加上大整数的乘法运算。

修改绝对值比较

上次写的绝对值的比较没有事先好好分析下,直接逐情况排除,代码非常难看。

这次看到别人很简洁的代码。由于输出只可能是-1,0,1. 可以逐渐剥离-1和1的情况剩下的就是0的情况。

见代码


	/*
* 修改的简洁版的比较绝对值
*/
public int Abscompare(DecimalBig that)
{
if(this.digits.length < that.digits.length) {
return -1;
}
if (that.digits.length < this.digits.length) {
return 1;
}
for(int i = 0; i < this.digits.length; i++) {
if(this.digits[i] < that.digits[i]) {
return -1;
}
if(that.digits[i] < this.digits[i]) {
return 1;
}
}
return 0;
}

乘法运算

这里乘法运算同样实行十进制一样的简单的运算法则。

其实乘法还可以使用Karatsuba快速乘法、快速傅里叶变换乘法。对于特殊的平方运算

也有优化的算法。这都待后续补充。这里只实现简单的乘法。

具体见123456*123321的图示实例


第二个数组的每一位乘以第一个数组,得到一串数组,并错位相加。


具体执行见图示


这里会用到两个数组相加的方法

public static int[] Add(int[] x, int[] val)

这里有一个要注意的地方。就是数组的每一位是一个int型的数,逐位相乘时先转换成long型的数

运算。最后把long型的数转换成两位Radix=10^9进制的数。

对于带符号的运算,首先判断只要有一个因子是0乘积就是0,否则乘积的符号就是this.sign乘以that.sign.

(上版本代码有bug,已修复)


public DecimalBig Multiply(DecimalBig that)
{
if (this.sign==0||that.sign==0)
<span style="white-space:pre">
</span>return Zero;
int resultsign=this.sign;
int[] resultdigits={0};
for(int i=that.digits.length-1;i>=0;i--)
{
//建立数组默认全零
int[] addresult = new int[this.digits.length];
int carry=0;
for (int j=this.digits.length-1;j>=0;j--)
{
long addlong= (long)this.digits[j]*that.digits[i]+carry;
int lowbit=(int)(addlong%Radix);
carry=(int)(addlong/Radix);
addresult[j]=lowbit;
}
if (carry>0)
{
int[] temp = new int[this.digits.length + 1];
System.arraycopy(addresult, 0, temp, 1, addresult.length);
temp[0] = carry;
addresult = temp;
}
int[] temp2=new int[addresult.length+that.digits.length-1-i];
System.arraycopy(addresult, 0, temp2, 0, addresult.length);
resultdigits=Add(resultdigits, temp2);
}
return new DecimalBig(resultsign, resultdigits);
}


后面除法需要int数组乘以int数的运算,其实上面乘法里也包含了这样的运算,下面我单独列出来以备后面使用


/*
* 数组乘以一个int类型的数
*/
public int[] Multiplyint(int th[], int that)
{
if (th==Zero.digits||that==0)
return Zero.digits;
//建立数组默认全零
int[] addresult = new int[th.length];
int carry=0;
for (int j=th.length-1;j>=0;j--)
{
long addlong= (long)th[j]*that+carry;
int lowbit=(int)(addlong%Radix);
carry=(int)(addlong/Radix);
addresult[j]=lowbit;
}
if (carry>0)
{
int[] temp = new int[th.length + 1];
System.arraycopy(addresult, 0, temp, 1, addresult.length);
temp[0] = carry;
addresult = temp;
}
return addresult;
}







最后

以上就是贤惠烤鸡为你收集整理的自己动手写Java大整数《2》优化和乘法的全部内容,希望文章能够帮你解决自己动手写Java大整数《2》优化和乘法所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(42)

评论列表共有 0 条评论

立即
投稿
返回
顶部