java自定义大数进制可在262之间相互转换.docx
《java自定义大数进制可在262之间相互转换.docx》由会员分享,可在线阅读,更多相关《java自定义大数进制可在262之间相互转换.docx(26页珍藏版)》请在冰豆网上搜索。
java自定义大数进制可在262之间相互转换
java自定义大数(进制可在2~62之间相互转化)
闲着没事做,写了一个自定义大数,并实现了两个大数的加减乘除以及比较,以及2~62进制任意数(包括但不限于正整数与负整数)的相互转化
大数类:
BigNumber.java
/*
*0~9用0~9表示,10~35用A~Z表示,36~61用a~z表示
*/
@SuppressWarnings("serial")
publicclassBigNumberextendsException{
privateStringMyNumber;//大数
privateintSystemNumber;//进制数
publicBigNumber(){
this("0",10);
}
publicBigNumber(StringMyNumber){
this(MyNumber,10);
}
publicBigNumber(StringMyNumber,intSystemNumber){
this.MyNumber=MyNumber;
this.SystemNumber=SystemNumber;
this.Islegal();
}
publicStringgetMyNumber(){
returnthis.MyNumber;
}
publicvoidsetMyNumber(StringmyNumber){
this.MyNumber=myNumber;
}
publicintgetSystemNumber(){
returnthis.SystemNumber;
}
publicvoidsetSystemNumber(intsystemNumber){
this.SystemNumber=systemNumber;
}
publicvoidIslegal(){//判断该字符串是否合法
if(this.MyNumber==null||this.MyNumber.length()==0){//大数为空或大数字符串长度为0
throw(newNumberFormatException("错误!
大数为空或大数字符串长度为0"+this.MyNumber));
}
if(this.SystemNumber<=1||this.SystemNumber>=63){//进制数不合法
throw(newNumberFormatException("错误!
进制数不合法"+this.SystemNumber));
}
if(this.MyNumber.equals("+")||this.MyNumber.equals("-")||this.MyNumber.equals(".")){
throw(newNumberFormatException("错误!
大数不合法"+this.MyNumber));
}
if(this.MyNumber.equals("+.")||this.MyNumber.equals("-.")){
throw(newNumberFormatException("错误!
大数不合法"+this.MyNumber));
}
for(inti=0,a,k=-1;ia=Chartoint(this.MyNumber.charAt(i));
if(i!
=0&&(a==-1||a==-2)){
throw(newNumberFormatException("错误!
符号位只能在大数首部"+this.MyNumber.charAt(i)+"("+i+")"));
}
if(a>=this.SystemNumber||a==-4){
throw(newNumberFormatException("错误!
该字符不在该进制合法字符中"+this.MyNumber.charAt(i)+"("+i+")"));
}
if(a==-3){
if(k==-1){
k=i;
}else{
throw(newNumberFormatException("错误!
出现了第二个小数点"+this.MyNumber.charAt(i)+"("+i+")"));
}
}
}
}
protectedstaticStringAdd_Positive(Strings1,Strings2,intn){//自定义两个正数加法运算
StringIns1=getInteger(s1),Dos1=getDecimal(s1),Ins2=getInteger(s2),Dos2=getDecimal(s2);//分别获取整数部分及小数部分
intInlength=Math.max(Ins1.length(),Ins2.length()),Dolength=Math.max(Dos1.length(),Dos2.length());
Ins1=AddToLeft(Ins1,Inlength+1)+AddToRight(Dos1,Dolength);
Ins2=AddToLeft(Ins2,Inlength+1)+AddToRight(Dos2,Dolength);
Strings="";
for(inti=Inlength+Dolength,m,y=0;i>=0;i--){
m=Chartoint(Ins1.charAt(i))+Chartoint(Ins2.charAt(i))+y;
s=Inttochar(m%n)+s;
y=m/n;
}
intpointplace=s.length()-Dolength;
s=Format(s.substring(0,pointplace)+"."+s.substring(pointplace),true);
returns;
}
protectedstaticStringSub_Positive(Strings1,Strings2,intn){//自定义两个正数减法运算;
if(ComparetoString(s1,s2)<0){//如果s1return"-"+Sub_Positive(s2,s1,n);
}
StringIns1=getInteger(s1),Dos1=getDecimal(s1),Ins2=getInteger(s2),Dos2=getDecimal(s2);//分别获取整数部分及小数部分
intInlength=Math.max(Ins1.length(),Ins2.length()),Dolength=Math.max(Dos1.length(),Dos2.length());
StringR=getComplement(newBigNumber(AddToLeft(Ins2,Inlength)+"."+AddToRight(Dos2,Dolength),n)).MyNumber;
R=Add_Positive(s1,R,n);
s2="0."+AddToLeft("1",Dolength);
R=Add_Positive(R,s2,n);
returnFormat(R.substring
(1),true);
}
protectedstaticStringMult_Positive(Strings1,Strings2,intn){//自定义两个正数乘法运算;
StringIns1=getInteger(s1),Dos1=getDecimal(s1),Ins2=getInteger(s2),Dos2=getDecimal(s2);//分别获取整数部分及小数部分
Ins1+=Dos1;
Ins2+=Dos2;
int[]A=newint[Ins1.length()+Ins2.length()-1];
for(inti=Ins1.length()-1;i>=0;i--){
for(intj=Ins2.length()-1;j>=0;j--){
A[i+j]+=Chartoint(Ins1.charAt(i))*Chartoint(Ins2.charAt(j));
}
}
Strings="";
for(inti=A.length-1;i>=1;i--){
s=Inttochar(A[i]%n)+s;
A[i-1]+=A[i]/n;
}
s=Inttochar(A[0]/n)+""+Inttochar(A[0]%n)+s;//特别要注意+""
intpointlength=Dos1.length()+Dos2.length();//获取小数点后的位数
returnFormat(s.substring(0,s.length()-pointlength)+"."+s.substring(s.length()-pointlength),true);
}
protectedstaticStringDivision_Positive(Strings1,Strings2,intn,intf){//自定义两个正数相除(f为小数点后的位数,能被除尽,且小数点后的位数少于f,则直接返回结果);
StringIns1=getInteger(s1),Dos1=getDecimal(s1),Ins2=getInteger(s2),Dos2=getDecimal(s2);//分别获取整数部分及小数部分
intDolength=Math.max(Dos1.length(),Dos2.length());
Ins1+=AddToRight(Dos1,Dolength);
Ins2+=AddToRight(Dos2,Dolength);
String[]B=newString[n];B[0]="0";
for(inti=1;iB[i]=Add_Positive(B[i-1],Ins2,n);//B[i]=Mult_Positive(Ins2,Inttochar(i)+"",n);
}
inti=Math.min(Ins1.length(),Ins2.length())-2,j;
StringDs0="",Ds1=Ins1.substring(0,i);//初始化整数部分余数部分
while(true){
if(i!
=Ins1.length()){
if(iDs1+=Ins1.charAt(i);
}else{
Ds1+="0";
if(Ds1.equals("00")||i-Ins1.length()-1==f){
break;
}
}
//下面开始求Ds1/Ins2的整数部分及余数,结果分别赋值为Ds0,Ds1;采用二分查找获取整数部分
j=Binary(B,Ds1);
Ds0+=Inttochar(j);
Ds1=Sub_Positive(Ds1,B[j],n);
}else{
Ds0+=".";
}
i++;
}
returnFormat(Ds0,true);
}
protectedstaticintBinary(String[]A,Stringkey){//二分查找key(数组A已经按从小到大的顺序排好序)
intlow=0,height=A.length-1,middle,Compare;
while(low<=height){
middle=(low+height)/2;
Compare=ComparetoString(key,A[middle]);
if(Compare==0){
returnmiddle;
}elseif(Compare>0){
low=middle+1;
}else{
height=middle-1;
}
}
returnheight;
}
publicBigNumberAdd(BigNumberb){//自定义加法运算
if(this.SystemNumber!
=b.SystemNumber){
throw(newNumberFormatException("错误!
这两个大数进制数不一致("+this.SystemNumber+","+b.SystemNumber+")"));
}
Strings;
if(IsPositive(this.MyNumber)&&IsPositive(b.MyNumber)){
s=Add_Positive(this.MyNumber,b.MyNumber,this.SystemNumber);
}elseif(IsPositive(this.MyNumber)&&!
IsPositive(b.MyNumber)){
s=Sub_Positive(this.MyNumber,Opposite(b.MyNumber),this.SystemNumber);
}elseif(!
IsPositive(this.MyNumber)&&IsPositive(b.MyNumber)){
s=Sub_Positive(b.MyNumber,Opposite(this.MyNumber),this.SystemNumber);
}else{
s=Add_Positive(Opposite(this.MyNumber),Opposite(b.MyNumber),this.SystemNumber);
s=(s.equals("0")?
"":
"-")+s;
}
returnnewBigNumber(s,this.SystemNumber);
}
publicBigNumberSub(BigNumberb){//自定义减法运算
returnthis.Add(newBigNumber(Opposite(b.MyNumber),b.SystemNumber));
}
publicBigNumberMult(BigNumberb){//自定义乘法运算
if(this.SystemNumber!
=b.SystemNumber){
throw(newNumberFormatException("错误!
这两个大数进制数不一致("+this.SystemNumber+","+b.SystemNumber+")"));
}
Strings;
if(IsPositive(this.MyNumber)&&IsPositive(b.MyNumber)){
s=Mult_Positive(this.MyNumber,b.MyNumber,this.SystemNumber);
}elseif(IsPositive(this.MyNumber)&&!
IsPositive(b.MyNumber)){
s=Mult_Positive(this.MyNumber,Opposite(b.MyNumber),this.SystemNumber);
s=(s.equals("0")?
"":
"-")+s;
}elseif(!
IsPositive(this.MyNumber)&&IsPositive(b.MyNumber)){
s=Mult_Positive(Opposite(this.MyNumber),b.MyNumber,this.SystemNumber);
s=(s.equals("0")?
"":
"-")+s;
}else{
s=Mult_Positive(Opposite(this.MyNumber),Opposite(b.MyNumber),this.SystemNumber);
}
returnnewBigNumber(s,this.SystemNumber);
}
publicBigNumberDivision(BigNumberb,intf){//自定义除法运算(f为小数点后的位数,能被除尽,且小数点后的位数少于f,则直接返回精确结果);
if(b.toString().equals("-0")||b.toString().equals("0")){
throw(newNumberFormatException("错误!
除数不能为零:
"+b));
}
if(this.SystemNumber!
=b.SystemNumber){
throw(newNumberFormatException("错误!
这两个大数进制数不一致!
("+this.SystemNumber+","+b.SystemNumber+")"));
}
if(f<0){
throw(newNumberFormatException("错误!
小数点后的位数应为非负值!
("+f+")"));
}
Strings;
if(IsPositive(this.MyNumber)&&IsPositive(b.MyNumber)){
s=Division_Positive(this.MyNumber,b.MyNumber,this.SystemNumber,f);
}elseif(IsPositive(this.MyNumber)&&!
IsPositive(b.MyNumber)){
s=Division_Positive(this.MyNumber,Opposite(b.MyNumber),this.SystemNumber,f);
s=(s.equals("0")?
"":
"-")+s;
}elseif(!
IsPositive(this.MyNumber)&&IsPositive(b.MyNumber)){
s=Division_Positive(Opposite(this.MyNumber),b.MyNumber,this.SystemNumber,f);
s=(s.equals("0")?
"":
"-")+s;
}else{
s=Division_Positive(Opposite(this.MyNumber),Opposite(b.MyNumber),this.SystemNumber,f);
}
returnnewBigNumber(s,this.SystemNumber);
}
publicBigNumberDivision(BigNumberb){//自定义除法运算,默认为保留50位小数(若能被除尽,且小数点后的位数少于50,则直接返回精确结果);
returnDivision(b,50);
}
protectedstaticintComparetoString(Strings1,Strings2){//判断两个正数的大小s1>s2返回1,s1=s2返回0,s1StringIns1=getInteger(s1),Dos1=getDecimal(s1),Ins2=getInteger(s2),Dos2=getDecimal(s2);
intDolength=Math.max(Dos1.length(),Dos2.length());
Ins1+=AddToRight(Dos1,Dolength);
Ins2+=AddToRight(Dos2,Dolength);
if(Ins1.length()>Ins2.length()){
return1;
}elseif(Ins1.length()return-1;
}
for(inti=0;iif(Ins1.charAt(i)>Ins2.charAt(i)){
return1;
}elseif(Ins1.charAt(i)return-1;
}
}
return0;
}
publicintCompareto(BigNumberb){
if(this.SystemNumber!
=b.SystemNumber){
throw(newNumberFormatException("错误!
这两个大数进制数不一致,暂时无法比较("+this.SystemNumber+","+b.SystemNumber+")"));
}
Strings1=Format(this.MyNumber,false),s2=Format(b.MyNumber,false);
if(IsPositive(s1)&&IsPositive(s2)){
returnComparetoString(s1,s2);//inta=s1.CompareTo(s2);returna!
=0?
(a>0?
1:
-1):
0;
}elseif(IsPositive(s1)&&!
IsPositive(s2)){
return1;
}elseif(!
IsPositive(s1)&&IsPositive(s2)){
return-1;
}else{
return-ComparetoString(s1.substring
(1),s2.substring
(1));
}
}
protectedstaticStringConver1(longn,intR){//将十进制数n转换为R进制数
if(R==10){
returnn+"";
}
Strings="";
while(true){
s=Inttochar((int)(n%R))+s;
n/=R;
if(n==0){
returns;
}
}
}
/*
*将R1进制正整数s转化为R2进制数
*(由于Conversion频繁调用该函数,为提高效率,引