之前已经完成了大整数的表示、绝对值的比较大小、取负值、加减法运算以及乘法运算。具体见前两篇博客(自己动手写Java * )。
这里添加除法运算。
另外看到作者Pauls Gedanken在blog(http://paul-ebermann.tumblr.com/post/6312290327/big-numbers-selfmade-part-2-14-conversion-from)中的转换十进制数到大整数的方法,这里一并列出。
除法
除法使用经典的除法法则,但是有几个需要注意的问题,下面列出。
1,除数是0的问题;
2,两者相等,输出1余数是被除数;
3,除数比较大,直接输出0,余数是被除数
4,子数组长度和除数数组长度相等或者大1,相等时候结果由子数组第一位除以除数第一位决定,
大1时候结果通过子数组头两位除以除数第一位决定
5,判定结果第一位是否为0.
我们看下简单的图示例子,看看除法的具体操作
/* * 除法 */ public DecimalBig Divide(DecimalBig that) { if (that.Compare(Zero)==0) throw new IllegalArgumentException("Divided by 0!"); if (this.Abscompare(that)==-1) return Zero; if (this.Abscompare(that)==0) return One; int thislength=this.digits.length; int thatlength=that.digits.length; int[] mulres=new int[thatlength]; System.arraycopy(this.digits, 0, mulres, 0, thatlength); int digitdivide=0; int[] result=new int[thislength-thatlength+1]; for (int i=0; i<thislength-thatlength;i++) { if (Arraycompare(mulres,that.digits)==-1) { digitdivide=0; } else { if (mulres.length==that.digits.length) digitdivide=mulres[0]/that.digits[0]; else{ long firtwei=(long)mulres[0]*Radix+mulres[1]; digitdivide=(int)firtwei/that.digits[0]; } int[] temp=Multiplyint(that.digits, digitdivide); if (Arraycompare(mulres,temp)==-1){ digitdivide-=1; temp=Substract(temp,that.digits); } mulres=Substract(mulres, temp); } result[i]=digitdivide; if (mulres.length==1&&mulres[0]==0){ mulres[0]=this.digits[i+thatlength]; }else{ int[] temp2=new int[mulres.length+1]; System.arraycopy(mulres, 0, temp2, 0, mulres.length); temp2[mulres.length]=this.digits[i+thatlength]; mulres=temp2; } } if (Arraycompare(mulres,that.digits)==-1) { digitdivide=0; } else { if (mulres.length==that.digits.length) digitdivide=mulres[0]/that.digits[0]; else{ long firtwei=(long)mulres[0]*Radix+mulres[1]; long ttt=firtwei/that.digits[0]; digitdivide=(int) ttt; } int[] temp=Multiplyint(that.digits, digitdivide); if (Arraycompare(mulres,temp)==-1){ digitdivide-=1; temp=Substract(temp,that.digits); } mulres=Substract(mulres, temp); } /* * 最后的mulres就是余数。 */ result[thislength-thatlength]=digitdivide; /* * 去掉首位的零 */ int i=0; while(i<result.length&&result[i]==0) i++; //截取非零项 int[] temp = new int[result.length-i]; System.arraycopy(result, i, temp, 0, result.length-i); result = temp; return new DecimalBig(1, result); } /* * 除法余数 */ public DecimalBig DivideReminder(DecimalBig that) { if (that.Compare(Zero)==0) throw new IllegalArgumentException("Divided by 0!"); if (this.Abscompare(that)==-1) return this; if (this.Abscompare(that)==0) return Zero; int thislength=this.digits.length; int thatlength=that.digits.length; int[] mulres=new int[thatlength]; System.arraycopy(this.digits, 0, mulres, 0, thatlength); int digitdivide=0; int[] result=new int[thislength-thatlength+1]; for (int i=0; i<thislength-thatlength;i++) { if (Arraycompare(mulres,that.digits)==-1) { digitdivide=0; } else { if (mulres.length==that.digits.length) digitdivide=mulres[0]/that.digits[0]; else{ long firtwei=(long)mulres[0]*Radix+mulres[1]; digitdivide=(int)firtwei/that.digits[0]; } int[] temp=Multiplyint(that.digits, digitdivide); if (Arraycompare(mulres,temp)==-1){ digitdivide-=1; temp=Substract(temp,that.digits); } mulres=Substract(mulres, temp); } result[i]=digitdivide; if (mulres.length==1&&mulres[0]==0){ mulres[0]=this.digits[i+thatlength]; }else{ int[] temp2=new int[mulres.length+1]; System.arraycopy(mulres, 0, temp2, 0, mulres.length); temp2[mulres.length]=this.digits[i+thatlength]; mulres=temp2; } } if (Arraycompare(mulres,that.digits)==-1) { digitdivide=0; } else { if (mulres.length==that.digits.length) digitdivide=mulres[0]/that.digits[0]; else{ long firtwei=(long)mulres[0]*Radix+mulres[1]; long ttt=firtwei/that.digits[0]; digitdivide=(int) ttt; } int[] temp=Multiplyint(that.digits, digitdivide); if (Arraycompare(mulres,temp)==-1){ digitdivide-=1; temp=Substract(temp,that.digits); } mulres=Substract(mulres, temp); } /* * 最后的mulres就是余数。 */ return new DecimalBig(1, mulres); }
十进制转换
引自Pauls Gedanken的方法
/**引用 * Pauls Gedanken在bloghttp://paul-ebermann.tumblr.com/post/6312290327/big-numbers-selfmade-part-2-14-conversion-from * 中的方法 * creates a DecimalBigInt from a decimal representation. * @param decimal a string of decimal digits. * @throws NumberFormatException if the number is not in * correct decimal format, e.g. if it contains any characters * outside of 0..9. */ public static DecimalBig valueOf(int si, String decimal) { int decLen = decimal.length(); int bigLen = (decLen-1) / Radix_Decimal_length + 1; // length of first block int firstSome = decLen - (bigLen-1) * Radix_Decimal_length; int[] digits = new int[bigLen]; for(int i = 0; i < bigLen ; i++) { String block = decimal.substring(Math.max(firstSome + (i-1)*Radix_Decimal_length, 0), firstSome + i *Radix_Decimal_length); digits[i] = Integer.parseInt(block); } return new DecimalBig(si, digits); }