上周粗略计划自己写Java下的大整数运算。
后来仔细想想其实自己动手写大整数运算有1好2不好。2个不好分别是:
1,肯定没有Java内置的BigInteger安全快速;2,自己写的大数包只能自己使用,不具有可移植性。
但是还有一个大大的好处就是
1,促进自己学习和弄清楚大数运算的机制,对自己进步有帮助。
所以我决定开始继续写下去。
开始在上篇计划中,我大概列出了会遇到的问题。下面我首先解决大数的表示、绝对值的比较大小、取负值和加减法运算。
后面我会不断添加乘法,除法,mod运算等。
private int[] digits;
也就是digits[0] 表示最高位,digits[digits.length] 表示最低位
private int sign;
public DecimalBig(int sign, int[] digits)
{
for(int i=0; iRadix)
throw new IllegalArgumentException("digit " + digits[i] +
" out of range!");
}
this.sign = sign;
this.digits = digits;
}
public int AbsCompare(DecimalBig that)
{
int result =0;
if (this.digits.length>that.digits.length)
result=1;
else{
if (this.digits.lengththat.digits[i])
result=1;
else
result=-1;
}
}
}
}
return result;
}
public DecimalBig negate()
{
return new DecimalBig(-this.sign, this.digits);
}
见下面代码
/**
*
*/
/**
* @author Xue
* at 2014.7.20
*/
public class DecimalBig {
/*
* 采用10^9进制的计算
*/
final static int Radix = 1000000000;
/*
* 美俄基数十进制的长度
*/
final static int Radix_Dicimal_length=9;
/*
* 每一个大整数都表示成一串int类型的数
*/
private int[] digits;
/*
* 符号,其中-1代表负数,0代表0,1代表正数
*/
private int sign;
/*
* 构造函数,这里选择的是小头高位,大头低位的方法存储的数据
*/
public DecimalBig(int sign, int[] digits)
{
for(int i=0; iRadix)
throw new IllegalArgumentException("digit " + digits[i] +
" out of range!");
}
this.sign = sign;
this.digits = digits;
}
private static int[] ONE={1};
public static final DecimalBig Zero=new DecimalBig(0, new int[0]);
public static final DecimalBig One=new DecimalBig(1, ONE);
/*
* 绝对值大小的比较,this 大则返回1,小返回1,相等返回0
*/
public int AbsCompare(DecimalBig that)
{
int result =0;
if (this.digits.length>that.digits.length)
result=1;
else{
if (this.digits.lengththat.digits[i])
result=1;
else
result=-1;
}
}
}
}
return result;
}
/*
* 反转符号,
*/
public DecimalBig negate()
{
return new DecimalBig(-this.sign, this.digits);
}
/*
* 返回绝对值;
*/
public DecimalBig abs()
{
return this.sign>=0?this:this.negate();
}
/*
* 加法,
*/
public DecimalBig Add(DecimalBig that)
{
//this 是 0
if (this.sign==0)
return that;
//that 是0
if (that.sign==0)
return this;
//相同符号
if (that.sign==this.sign)
return new DecimalBig(this.sign, Add(this.digits,that.digits));
//不同符号
if (this.AbsCompare(that)==0)
return Zero;
if (this.AbsCompare(that)==1)
return new DecimalBig(this.sign, Substract(this.digits,that.digits));
return new DecimalBig(that.sign, Substract(that.digits,this.digits));
}
/*
* 减法
*/
public DecimalBig substract(DecimalBig that)
{
//this 是 0
if (this.sign==0)
return that.negate();
//that 是0
if (that.sign==0)
return this;
//不同符号
if (that.sign!=this.sign)
return new DecimalBig(this.sign, Add(this.digits,that.digits));
//相同符号
if (this.AbsCompare(that)==0)
return Zero;
if (this.AbsCompare(that)==1)
return new DecimalBig(this.sign, Substract(this.digits,that.digits));
return new DecimalBig(that.sign, Substract(that.digits,this.digits));
}
/*
* 两个数组的加法
*/
public static int[] Add(int[] x, int[] val)
{
int[] MaxBig, MinBig;
/*
* 拷贝较长的数到MaxBig较短的数到MinBig
*/
if (x.length=0;i--)
{
int extadd=0;
if (i>MaxBig.length-MinBig.length-1)
extadd=MinBig[i-(MaxBig.length-MinBig.length)];
else
extadd=0;
int DigitSum=MaxBig[i]+extadd+carry;
addresult[i]=DigitSum%Radix;
carry=DigitSum/Radix;
}
/*
* 最高位哟啊是有进位的话,拉长一位
*/
if (carry==1)
{
int[] temp = new int[MaxBig.length + 1];
System.arraycopy(addresult, 0, temp, 1, MaxBig.length);
temp[0] = carry;
addresult = temp;
}
return addresult;
}
/*
* 两个数组的减法;
*/
public static int[] Substract(int[] Big, int[] little)
{
/*
* 建立要返回的数组addresult;进位制记为carry
*/
int[] subresult = new int[Big.length];
int carry=0;
/*
* 简单的进位加法
*/
for (int i=Big.length-1;i>=0;i--)
{
int extsub=0;
if (i>Big.length-little.length-1)
extsub=little[i-(Big.length-little.length)];
else
extsub=0;
int Digitsub=Big[i]-extsub-carry;
if(Digitsub<0){
subresult[i]=Digitsub+Radix;
carry=1;
} else{
subresult[i]=Digitsub;
carry=0;
}
}
/*
* 去掉高位的零
*/
int i=0;
while(i