使用java 和 php 不限位數 進行進制轉換 (自定義BigNumber)

轉自:https://blog.csdn.net/xinshijimanon/article/details/46681191


  1. /* 
  2.  * 0~9用0~9表示,10~35用A~Z表示,36~61用a~z表示 
  3.  */  
  4. @SuppressWarnings("serial")  
  5. public class BigNumber extends Exception{     
  6.     private String MyNumber;//大數      
  7.     private int SystemNumber;//進制數  
  8.     public BigNumber(){  
  9.         this("0",10);  
  10.     }  
  11.     public BigNumber(String MyNumber){  
  12.         this(MyNumber,10);  
  13.     }  
  14.     public BigNumber(String MyNumber,int SystemNumber){  
  15.         this.MyNumber=MyNumber;  
  16.         this.SystemNumber=SystemNumber;  
  17.         this.Islegal();   
  18.     }  
  19.     public String getMyNumber() {  
  20.         return this.MyNumber;  
  21.     }  
  22.     public void setMyNumber(String myNumber) {  
  23.         this.MyNumber = myNumber;  
  24.     }  
  25.     public int getSystemNumber() {  
  26.         return this.SystemNumber;  
  27.     }  
  28.     public void setSystemNumber(int systemNumber) {  
  29.         this.SystemNumber = systemNumber;  
  30.     }  
  31.     public void Islegal(){//判斷該字符串是否合法  
  32.         if(this.MyNumber==null||this.MyNumber.length()==0){//大數爲空或大數字符串長度爲0  
  33.             throw (new  NumberFormatException("錯誤!大數爲空或大數字符串長度爲0 "+this.MyNumber));  
  34.         }  
  35.         if(this.SystemNumber<=1||this.SystemNumber>=63){//進制數不合法  
  36.             throw (new  NumberFormatException("錯誤!進制數不合法 "+this.SystemNumber));  
  37.         }  
  38.         if(this.MyNumber.equals("+")||this.MyNumber.equals("-")||this.MyNumber.equals(".")){  
  39.             throw (new  NumberFormatException("錯誤!大數不合法 "+this.MyNumber));  
  40.         }  
  41.         if(this.MyNumber.equals("+.")||this.MyNumber.equals("-.")){  
  42.             throw (new  NumberFormatException("錯誤!大數不合法 "+this.MyNumber));  
  43.         }  
  44.         for(int i=0,a,k=-1;i<this.MyNumber.length();i++){  
  45.             a=Chartoint(this.MyNumber.charAt(i));  
  46.             if(i!=0&&(a==-1||a==-2)){  
  47.                 throw (new  NumberFormatException("錯誤!符號位只能在大數首部 "+this.MyNumber.charAt(i)+"("+i+")"));  
  48.             }  
  49.             if(a>=this.SystemNumber||a==-4){  
  50.                 throw (new  NumberFormatException("錯誤!該字符不在該進制合法字符中 "+this.MyNumber.charAt(i)+"("+i+")"));  
  51.             }  
  52.             if(a==-3){  
  53.                 if(k==-1){  
  54.                     k=i;  
  55.                 }else{  
  56.                     throw (new  NumberFormatException("錯誤!出現了第二個小數點 "+this.MyNumber.charAt(i)+"("+i+")"));  
  57.                 }  
  58.             }  
  59.         }  
  60.     }  
  61.     private static String Add_Positive(String s1,String s2,int n){//自定義兩個正數加法運算       
  62.         String Ins1=getInteger(s1),Dos1=getDecimal(s1),Ins2=getInteger(s2),Dos2=getDecimal(s2);//分別獲取整數部分及小數部分  
  63.         int Inlength=Math.max(Ins1.length(), Ins2.length()),Dolength=Math.max(Dos1.length(), Dos2.length());  
  64.         Ins1=AddToLeft(Ins1,Inlength+1)+AddToRight(Dos1,Dolength);  
  65.         Ins2=AddToLeft(Ins2,Inlength+1)+AddToRight(Dos2,Dolength);  
  66.         String s="";  
  67.         for(int i=Inlength+Dolength,m,y=0;i>=0;i--){  
  68.             m=Chartoint(Ins1.charAt(i))+Chartoint(Ins2.charAt(i))+y;  
  69.             s=Inttochar(m%n)+s;  
  70.             y=m/n;  
  71.         }  
  72.         int pointplace=s.length()-Dolength;  
  73.         s=Format(s.substring(0,pointplace)+"."+s.substring(pointplace),true);     
  74.         return s;  
  75.     }         
  76.     private static String Sub_Positive(String s1,String s2,int n){//自定義兩個正數減法運算;  
  77.         if(ComparetoString(s1,s2)<0){//如果s1<s2則返回-(s2-s1)  
  78.             return "-"+Sub_Positive(s2,s1,n);  
  79.               
  80.         }                     
  81.         String Ins1=getInteger(s1),Dos1=getDecimal(s1),Ins2=getInteger(s2),Dos2=getDecimal(s2);//分別獲取整數部分及小數部分  
  82.         int Inlength=Math.max(Ins1.length(), Ins2.length()),Dolength=Math.max(Dos1.length(), Dos2.length());  
  83.         String R=getComplement(new BigNumber(AddToLeft(Ins2,Inlength)+"."+AddToRight(Dos2,Dolength),n)).MyNumber;  
  84.         R=Add_Positive(s1,R,n);  
  85.         s2="0."+AddToLeft("1",Dolength);  
  86.         R=Add_Positive(R,s2,n);  
  87.         return Format(R.substring(1),true);       
  88.     }  
  89.     private static String Mult_Positive(String s1,String s2,int n){//自定義兩個正數乘法運算;   
  90.         String Ins1=getInteger(s1),Dos1=getDecimal(s1),Ins2=getInteger(s2),Dos2=getDecimal(s2);//分別獲取整數部分及小數部分  
  91.         Ins1+=Dos1;  
  92.         Ins2+=Dos2;       
  93.         int[]A=new int[Ins1.length()+Ins2.length()-1];  
  94.         for(int i=Ins1.length()-1;i>=0;i--){  
  95.             for(int j=Ins2.length()-1;j>=0;j--){  
  96.                 A[i+j]+=Chartoint(Ins1.charAt(i))*Chartoint(Ins2.charAt(j));  
  97.             }  
  98.         }  
  99.         String s="";  
  100.         for(int i=A.length-1;i>=1;i--){  
  101.             s=Inttochar(A[i]%n)+s;  
  102.             A[i-1]+=A[i]/n;  
  103.         }  
  104.         s=Inttochar(A[0]/n)+""+Inttochar(A[0]%n)+s;//特別要注意+""  
  105.         int pointlength=Dos1.length()+Dos2.length();//獲取小數點後的位數  
  106.         return Format(s.substring(0,s.length()-pointlength)+"."+s.substring(s.length()-pointlength),true);        
  107.     }     
  108.     private static String  Division_Positive(String s1, String s2,int n,int f){//自定義兩個正數相除(f爲小數點後的位數,能被除盡,且小數點後的位數少於f,則直接返回結果);  
  109.         String Ins1=getInteger(s1),Dos1=getDecimal(s1),Ins2=getInteger(s2),Dos2=getDecimal(s2); //分別獲取整數部分及小數部分       
  110.         int Dolength=Math.max(Dos1.length(), Dos2.length());  
  111.         Ins1+=AddToRight(Dos1,Dolength);  
  112.         Ins2+=AddToRight(Dos2,Dolength);  
  113.         String[]B=new String[n];B[0]="0";  
  114.         for(int i=1;i<n;i++){  
  115.             B[i]=Add_Positive(B[i-1],Ins2,n);//B[i]=Mult_Positive(Ins2,Inttochar(i)+"", n);  
  116.         }  
  117.         int i=Math.min(Ins1.length(), Ins2.length())-2,j;  
  118.         String Ds0="",Ds1=Ins1.substring(0,i);//初始化整數部分餘數部分           
  119.         while(true){  
  120.             if(i!=Ins1.length()){  
  121.                 if(i<Ins1.length()){  
  122.                     Ds1+=Ins1.charAt(i);  
  123.                 }else{  
  124.                     Ds1+="0";  
  125.                     if(Ds1.equals("00")||i-Ins1.length()-1==f){  
  126.                         break;  
  127.                     }  
  128.                 }  
  129.                 //下面開始求Ds1/Ins2的整數部分及餘數,結果分別賦值爲Ds0,Ds1;採用二分查找獲取整數部分  
  130.                 j=Binary(B,Ds1);  
  131.                 Ds0+=Inttochar(j);  
  132.                 Ds1=Sub_Positive(Ds1,B[j],n);                 
  133.             }else{  
  134.                 Ds0+=".";  
  135.             }  
  136.             i++;  
  137.         }  
  138.         return Format(Ds0,true);      
  139.     }  
  140.     private static int Binary(String[]A,String key){//二分查找key(數組A已經按從小到大的順序排好序)  
  141.         int low=0,height=A.length-1,middle,Compare;  
  142.         while(low<=height){  
  143.             middle=(low+height)/2;  
  144.             Compare=ComparetoString(key,A[middle]);  
  145.             if(Compare==0){  
  146.                 return middle;  
  147.             }else if(Compare>0){  
  148.                 low=middle+1;  
  149.             }else{  
  150.                 height=middle-1;  
  151.             }  
  152.         }  
  153.         return height;  
  154.     }  
  155.     public BigNumber Add(BigNumber b){//自定義加法運算  
  156.         if(this.SystemNumber!=b.SystemNumber){  
  157.             throw (new  NumberFormatException("錯誤!這兩個大數進制數不一致 ("+this.SystemNumber+","+b.SystemNumber+")"));  
  158.         }  
  159.         String s;  
  160.         if(IsPositive(this.MyNumber)&&IsPositive(b.MyNumber)){  
  161.             s=Add_Positive(this.MyNumber,b.MyNumber,this.SystemNumber);  
  162.         }else if(IsPositive(this.MyNumber)&&!IsPositive(b.MyNumber)){  
  163.             s=Sub_Positive(this.MyNumber,Opposite(b.MyNumber),this.SystemNumber);             
  164.         }else if(!IsPositive(this.MyNumber)&&IsPositive(b.MyNumber)){             
  165.             s=Sub_Positive(b.MyNumber,Opposite(this.MyNumber),this.SystemNumber);  
  166.         }else{  
  167.             s=Add_Positive(Opposite(this.MyNumber),Opposite(b.MyNumber),this.SystemNumber);  
  168.             s=(s.equals("0")?"":"-")+s;  
  169.         }  
  170.         return new BigNumber(s,this.SystemNumber);  
  171.     }  
  172.     public BigNumber Sub(BigNumber b){//自定義減法運算  
  173.         return this.Add(new BigNumber(Opposite(b.MyNumber),b.SystemNumber));  
  174.     }  
  175.     public BigNumber Mult(BigNumber b){//自定義乘法運算  
  176.         if(this.SystemNumber!=b.SystemNumber){  
  177.             throw (new  NumberFormatException("錯誤!這兩個大數進制數不一致 ("+this.SystemNumber+","+b.SystemNumber+")"));  
  178.         }  
  179.         String s;  
  180.         if(IsPositive(this.MyNumber)&&IsPositive(b.MyNumber)){  
  181.             s=Mult_Positive(this.MyNumber,b.MyNumber,this.SystemNumber);  
  182.         }else if(IsPositive(this.MyNumber)&&!IsPositive(b.MyNumber)){  
  183.             s=Mult_Positive(this.MyNumber,Opposite(b.MyNumber),this.SystemNumber);     
  184.             s=(s.equals("0")?"":"-")+s;  
  185.         }else if(!IsPositive(this.MyNumber)&&IsPositive(b.MyNumber)){             
  186.             s=Mult_Positive(Opposite(this.MyNumber),b.MyNumber,this.SystemNumber);  
  187.             s=(s.equals("0")?"":"-")+s;  
  188.         }else{  
  189.             s=Mult_Positive(Opposite(this.MyNumber),Opposite(b.MyNumber),this.SystemNumber);              
  190.         }  
  191.         return new BigNumber(s,this.SystemNumber);        
  192.     }  
  193.     public BigNumber Division(BigNumber b,int f){//自定義除法運算(f爲小數點後的位數,能被除盡,且小數點後的位數少於f,則直接返回精確結果);  
  194.         if(b.toString().equals("-0")||b.toString().equals("0")){  
  195.             throw (new  NumberFormatException("錯誤!除數不能爲零:"+b));  
  196.         }  
  197.         if(this.SystemNumber!=b.SystemNumber){  
  198.             throw (new  NumberFormatException("錯誤!這兩個大數進制數不一致! ("+this.SystemNumber+","+b.SystemNumber+")"));  
  199.         }  
  200.         if(f<0){  
  201.             throw (new  NumberFormatException("錯誤!小數點後的位數應爲非負值!("+f+")"));  
  202.         }  
  203.         String s;  
  204.         if(IsPositive(this.MyNumber)&&IsPositive(b.MyNumber)){  
  205.             s=Division_Positive(this.MyNumber,b.MyNumber,this.SystemNumber,f);  
  206.         }else if(IsPositive(this.MyNumber)&&!IsPositive(b.MyNumber)){  
  207.             s=Division_Positive(this.MyNumber,Opposite(b.MyNumber),this.SystemNumber,f);     
  208.             s=(s.equals("0")?"":"-")+s;  
  209.         }else if(!IsPositive(this.MyNumber)&&IsPositive(b.MyNumber)){             
  210.             s=Division_Positive(Opposite(this.MyNumber),b.MyNumber,this.SystemNumber,f);  
  211.             s=(s.equals("0")?"":"-")+s;  
  212.         }else{  
  213.             s=Division_Positive(Opposite(this.MyNumber),Opposite(b.MyNumber),this.SystemNumber,f);            
  214.         }  
  215.         return new BigNumber(s,this.SystemNumber);   
  216.     }  
  217.     public BigNumber Division(BigNumber b){//自定義除法運算,默認爲保留50位小數(若能被除盡,且小數點後的位數少於50,則直接返回精確結果);  
  218.         return Division(b,50);  
  219.     }  
  220.     private static int ComparetoString(String s1,String s2){//判斷兩個正數的大小s1>s2返回1,s1=s2返回0,s1<s2返回-1  
  221.         String Ins1=getInteger(s1),Dos1=getDecimal(s1),Ins2=getInteger(s2),Dos2=getDecimal(s2);  
  222.         int Dolength=Math.max(Dos1.length(), Dos2.length());  
  223.         Ins1+=AddToRight(Dos1,Dolength);  
  224.         Ins2+=AddToRight(Dos2,Dolength);  
  225.         if(Ins1.length()>Ins2.length()){  
  226.             return 1;  
  227.         }else if(Ins1.length()<Ins2.length()){  
  228.             return -1;  
  229.         }  
  230.         for(int i=0;i<Ins1.length();i++){  
  231.             if(Ins1.charAt(i)>Ins2.charAt(i)){  
  232.                 return 1;  
  233.             }else if(Ins1.charAt(i)<Ins2.charAt(i)){  
  234.                 return -1;  
  235.             }  
  236.         }  
  237.         return 0;  
  238.     }  
  239.     public int Compareto(BigNumber b){  
  240.         if(this.SystemNumber!=b.SystemNumber){  
  241.             throw (new  NumberFormatException("錯誤!這兩個大數進制數不一致 ,暫時無法比較("+this.SystemNumber+","+b.SystemNumber+")"));  
  242.         }  
  243.         String s1=Format(this.MyNumber,false),s2=Format(b.MyNumber,false);  
  244.         if(IsPositive(s1)&&IsPositive(s2)){  
  245.             return ComparetoString(s1,s2);//int a=s1.CompareTo(s2); return a!=0?(a>0?1:-1):0;  
  246.         }else if(IsPositive(s1)&&!IsPositive(s2)){  
  247.             return 1;  
  248.         }else if(!IsPositive(s1)&&IsPositive(s2)){  
  249.             return -1;  
  250.         }else{  
  251.             return -ComparetoString(s1.substring(1),s2.substring(1));  
  252.         }  
  253.     }  
  254.     private static String ConverFromTen(long n,int R){//將十進制數n轉換爲R進制數  
  255.         if(R==10){  
  256.             return n+"";  
  257.         }  
  258.         String s="";  
  259.         while(true){  
  260.             s=Inttochar((int)(n%R))+s;  
  261.             n/=R;  
  262.             if(n==0){  
  263.                 return s;  
  264.             }  
  265.         }         
  266.     }   
  267.     /* 
  268.      * 將R1進制正整數s轉化爲R2進制數  
  269.      * (由於Conversion頻繁調用該函數,爲提高效率,引入兩個輔助數組Hex1,Hex2): 
  270.      * Hex1[i]是十進制數i轉換爲R2進制數後的數,0<=i<=R1;Hex2[i]=Hex1[R1]^i,0<=i<=s.length() 
  271.      * Hex2[i]是十進制數R1轉換爲R2進制數後的i次方 
  272.      */  
  273.     private static String Conver(String s,int R2,String[]Hex1,String[]Hex2){  
  274.         String Ins="0";//初始化新進制對應的大數  
  275.         for(int i=0;i<s.length();i++){             
  276.             Ins=Add_Positive(Ins,Mult_Positive(Hex1[Chartoint(s.charAt(s.length()-1-i))],Hex2[i],R2),R2);                              
  277.         }  
  278.         return Ins;  
  279.     }  
  280.     private static String Conversion(String MyNumber,int R1,int R2,int N,int f){//將R1進制大數MyNumber轉換爲R2進制的大數(f爲小數點後的位數,能被除盡,且小數點後的位數少於f,則直接返回結果),N爲將MyNumber分組後每組字符串的長度;  
  281.         if(R2==R1){  
  282.             int a=getDecimal(MyNumber).length()-f;  
  283.             if(a>0){  
  284.                 return MyNumber.substring(0,MyNumber.length()-a);  
  285.             }  
  286.             return MyNumber;  
  287.         }  
  288.         if(MyNumber.charAt(0)=='+'||MyNumber.charAt(0)=='-'){  
  289.             char c=MyNumber.charAt(0);  
  290.             return c+Conversion(MyNumber.substring(1),R1,R2,N,f);  
  291.         }  
  292.         String[]Hex1=new String[R1+1];  
  293.         for(int i=0;i<=R1;i++){//將0~R1的所有數字轉換爲R2進制  
  294.             Hex1[i]=ConverFromTen(i,R2);  
  295.         }  
  296.         String[]Hex2=new String[N+1];Hex2[0]="1";  
  297.         for(int i=1;i<=N;i++){//求十進制數R1轉換爲R2進制數後的i次方  
  298.             Hex2[i]=Mult_Positive(Hex2[i-1],Hex1[R1],R2);  
  299.         }             
  300.         String Ins1=getInteger(MyNumber),Dos1=getDecimal(MyNumber);//獲取整數部分及小數部分          
  301.         /* 
  302.          * 經過計算當轉化後的R2進制數只需保留f位小數時,原R1進制數MyNumber只需保留a位 
  303.          * 當MyNumber小數位很多,而f較小時在一定程度上能提高效率 
  304.          */  
  305.         int a=(int)Math.ceil(f*Math.log(R2)/Math.log(R1))+1;  
  306.         if(a<=Dos1.length()){  
  307.             Dos1=Dos1.substring(0,a);  
  308.         }  
  309.           
  310.         Ins1=AddToLeft(Ins1,Ins1.length()+(N-Ins1.length()%N)%N);//擴充Ins1  
  311.         Dos1=AddToRight(Dos1,Dos1.length()+(N-Dos1.length()%N)%N);//擴充Dos1  
  312.         String Ins="0",Dos="0",x="1";//new BigNumber(Conver1(R1,R2),R2).Power(N).MyNumber;初始化新進制對應的大數的整數部分及小數部分 ,設置初值及權                       
  313.         int Count=Math.max(Ins1.length()/N,Dos1.length()/N);//循環次數     
  314.         for(int i=0,i1=Ins1.length()/N,i2=Dos1.length()/N;i<Count;i++){                
  315.             if(i<i1){  
  316.                 Ins=Add_Positive(Ins,Mult_Positive(Conver(Ins1.substring(Ins1.length()-(i+1)*N,Ins1.length()-i*N),R2,Hex1,Hex2),x,R2),R2);  
  317.             }  
  318.             if(i<i2){                                                      
  319.                 Dos=Add_Positive(Dos,Mult_Positive(Conver(Dos1.substring(Dos1.length()-(i+1)*N,Dos1.length()-i*N),R2,Hex1,Hex2),x,R2),R2);  
  320.                 if(i==i2-1){  
  321.                     Dos=Division_Positive(Dos,Mult_Positive(x,Hex2[N],R2),R2,f);  
  322.                 }  
  323.             }     
  324.             x=Mult_Positive(x,Hex2[N],R2);  
  325.         }  
  326.         return Ins+Dos.substring(1);//或Add_Positive(Ins,Dos,R2);                      
  327.     }  
  328.     public BigNumber HexConversion(int R,int N,int f){  
  329.         if(R<=1||R>=63){//進制數不合法  
  330.             throw (new  NumberFormatException("錯誤!進制數不合法 "+this.SystemNumber));  
  331.         }  
  332.         if(N<=0){  
  333.             throw (new  NumberFormatException("錯誤!每小組的字符串長度不能小於1!("+N+")"));  
  334.         }  
  335.         if(f<0){  
  336.             throw (new  NumberFormatException("錯誤!小數點後的位數應爲非負值!("+f+")"));  
  337.         }  
  338.         return new BigNumber(Conversion(this.MyNumber,this.SystemNumber,R,N,f),R);  
  339.     }    
  340.     public BigNumber HexConversion(int R,int f){  
  341.         int N=(int)Math.pow(Math.max(getInteger(this.MyNumber).length(),getDecimal(this.MyNumber).length()),0.6)+1;  
  342.         return HexConversion(R,N,f);  
  343.     }   
  344.     public BigNumber HexConversion(int R){  
  345.         return HexConversion(R,50);  
  346.     }        
  347.       
  348.     /*public BigNumber Power(int n,int f){ 
  349.         if(n<0){ 
  350.             return new BigNumber("1",this.SystemNumber).Division(this.Power(-n,f),f); 
  351.         } 
  352.         String s=ConverFromTen(n,2); 
  353.         BigNumber r=new BigNumber("1",this.SystemNumber),k=this; 
  354.         for(int i=0;i<s.length();i++){                
  355.             if(s.charAt(s.length()-1-i)=='1'){ 
  356.                 r=r.Mult(k); 
  357.             } 
  358.             k=k.Mult(k); 
  359.         }        
  360.         return r;                
  361.     } 
  362.     public BigNumber Power(int n){ 
  363.         return Power(n,50); 
  364.     }*/  
  365.       
  366.     private static BigNumber getComplement(BigNumber b){//獲得 b的每位取反後的大數  
  367.         String s="";  
  368.         char c=b.MyNumber.charAt(0);  
  369.         if(c=='+'||c=='-'||c=='.'){  
  370.             s+=c;  
  371.         }else{  
  372.             s+=Inttochar(b.SystemNumber-1-Chartoint(c));  
  373.         }  
  374.         for(int i=1;i<b.MyNumber.length();i++){  
  375.             c=b.MyNumber.charAt(i);  
  376.             if(c=='.'){  
  377.                 s+=c;  
  378.             }else{  
  379.                 s+=Inttochar(b.SystemNumber-1-Chartoint(c));  
  380.             }  
  381.         }  
  382.         return new BigNumber(s,b.SystemNumber);  
  383.     }  
  384.     private static String AddToLeft(String s,int length){//若s的長度大於或等於length,則直接返回s,否則字符串s左邊補零,直到s長度達到length  
  385.         if(s.length()>=length){  
  386.             return s;  
  387.         }  
  388.         while(s.length()<length){  
  389.             s="0000000000"+s;  
  390.         }  
  391.         return s.substring(s.length()-length,s.length());  
  392.     }  
  393.     private static String AddToRight(String s,int length){//若s的長度大於或等於length,則直接返回s,否則字符串s右邊補零,直到s長度達到length  
  394.         if(s.length()>=length){  
  395.             return s;  
  396.         }  
  397.         while(s.length()<length){  
  398.             s=s+"0000000000";  
  399.         }  
  400.         return s.substring(0,length);  
  401.     }  
  402.     private static String Format(String MyNumber,boolean DealZero){//對於合法的大數,格式化大數爲a.b(或-a.b)的形式,若b=0且DealZero爲真則返回a(或-a)的形式  
  403.         new BigNumber(MyNumber,62);//若該大數不合法則拋出異常  
  404.         String s;  
  405.         if(MyNumber.charAt(0)=='+'||MyNumber.charAt(0)=='-'){  
  406.             s=MyNumber.substring(1);  
  407.         }else{  
  408.             s=MyNumber;  
  409.         }  
  410.         if(getPointPlace(s)==0){  
  411.             s="0"+s;  
  412.         }else if(getPointPlace(s)==s.length()-1){  
  413.             s=s+"0";  
  414.         }else if(getPointPlace(s)==s.length()){  
  415.             s=s+".0";  
  416.         }  
  417.         int Ins=0,Dos=s.length(),pointplace=getPointPlace(s);  
  418.         for(int i=0;i<pointplace-1;i++){  
  419.             if(s.charAt(i)=='0'){  
  420.                 Ins++;  
  421.             }else{  
  422.                 break;  
  423.             }  
  424.         }         
  425.         for(int i=s.length()-1;i>pointplace+1;i--){  
  426.             if(s.charAt(i)=='0'){  
  427.                 Dos--;  
  428.             }else{  
  429.                 break;  
  430.             }  
  431.         }     
  432.         s=(MyNumber.charAt(0)=='-'?"-":"")+s.substring(Ins,Dos);  
  433.         if(DealZero&&s.substring(s.length()-2).equals(".0")){  
  434.             return s.substring(0,s.length()-2);  
  435.         }else{  
  436.             return s;  
  437.         }  
  438.     }     
  439.     private static boolean IsPositive(String MyNumber){//判斷該大數是否爲正數(負數返回false,0和正數返回true)  
  440.         if(MyNumber.charAt(0)=='-'){  
  441.             return false;  
  442.         }  
  443.         return true;  
  444.     }  
  445.     private static int  getPointPlace(String MyNumber){//返回該大數小數點位置  
  446.         for(int i=0;i<MyNumber.length();i++){  
  447.             if(MyNumber.charAt(i)=='.'){  
  448.                 return i;  
  449.             }  
  450.         }  
  451.         return MyNumber.length();  
  452.     }     
  453.     private static String Abs(String MyNumber){//返回該大數的絕對值  
  454.         MyNumber=Format(MyNumber,true);  
  455.         return MyNumber.substring(MyNumber.charAt(0)=='-'?1:0);  
  456.     }  
  457.     private static String Opposite(String MyNumber){//返回該大數的相反數       
  458.         return MyNumber.charAt(0)=='-'?Abs(MyNumber):"-"+Abs(MyNumber);  
  459.     }  
  460.     private static String getInteger(String MyNumber){//返回該大數的整數部分       
  461.         MyNumber=Format(MyNumber,false);  
  462.         return MyNumber.substring(0,getPointPlace(MyNumber));  
  463.     }  
  464.     private static String getDecimal(String MyNumber){//返回該大數的小數部分   
  465.         MyNumber=Format(MyNumber,false);  
  466.         String s=getPointPlace(MyNumber)==MyNumber.length()?"0":MyNumber.substring(getPointPlace(MyNumber)+1);  
  467.         return (MyNumber.charAt(0)=='-'?"-":"")+s;    
  468.     }  
  469.     private static int Chartoint(char c){//字符化爲數字  
  470.         if(c>='0'&&c<='9'){  
  471.             return c-'0';  
  472.         }else if(c>='A'&&c<='Z'){  
  473.             return c-'A'+10;  
  474.         }else if(c>='a'&&c<='z'){  
  475.             return c-'a'+36;  
  476.         }else if(c=='+'){//正號  
  477.             return -1;  
  478.         }else if(c=='-'){//負號  
  479.             return -2;  
  480.         }else if(c=='.'){//小數點  
  481.             return -3;  
  482.         }else{//其他  
  483.             return -4;  
  484.         }  
  485.     }  
  486.     private static char Inttochar(int n){//數字化爲字符  
  487.         if(n>=0&&n<=9){//0~9用0~9表示  
  488.             return (char)(n+48);  
  489.         }else if(n>=10&&n<=35){//10~35用A~Z表示  
  490.             return (char)(n+55);  
  491.         }else if(n>=36&&n<=61){//36~61用a~z表示  
  492.             return (char)(n+61);  
  493.         }else{//小於0或大於61的數用'~'表示  
  494.             return '~';  
  495.         }  
  496.     }  
  497.     public String toString(){  
  498.         return Format(this.MyNumber,true);  
  499.     }     
  500. }  


順便寫了個測試類測試進制轉換的效果與效率

測試類:

[java] view plain copy
  1. public class TestBigNumber {  
  2.     public static void main(String[]args){  
  3.         String MyNumber="1313624242ADAFSFGDRG424242ADAF679707464342424242ADAFS24242ADAFSFGDRG424242ADAFFGDRG142356679707464342424242ADAFSFGDRG67866679707464342424242ADAFSFGDRG96068563556667970746V6679707464342424423536858686242ADAFSFGD69979RG67970746434242427979742ADAFS.FGDRG646676679707464342424242ADAFSFGDRG9707464342424242ADAFSFGDRG342424242ADAFSFGDRG67970746434266797074643426679707464342424242ADAFSFGDRG424242ADAFSFGDRG424242ADAFSFGDRG24242342426679707464342424242ADAFSFGDRG534364547455686679707464342424242ADAFSFGDRG6679707464342424242ADAFSFGDRGDADA6679707464342424242ADAFSFGDRGAFSFS6679707464342424242ADAFSFGDRG";  
  4.         int R1=39,R2=62,R3=2;  
  5.         int f=MyNumber.length()-MyNumber.indexOf('.')-1;  
  6.         BigNumber b=new BigNumber(MyNumber,R1);  
  7.         BigNumber b1,b2,b3,b4;  
  8.         long c1=System.currentTimeMillis();  
  9.         b1=b.HexConversion(R2, f);  
  10.         System.out.println("將"+b.getSystemNumber()+"進制數\n"+b.getMyNumber()+"轉化爲"+R2+"進制數並保留"+f+"位小數後去除無效位的結果爲:\n"+b1);  
  11.         long c2=System.currentTimeMillis();  
  12.         b2=b.HexConversion(R3, f);  
  13.         System.out.println("將"+b.getSystemNumber()+"進制數\n"+b.getMyNumber()+"轉化爲"+R3+"進制數並保留"+f+"位小數後去除無效位的結果爲:\n"+b2);  
  14.         long c3=System.currentTimeMillis();  
  15.         b3=b1.HexConversion(R1, f);  
  16.         System.out.println("將"+b1.getSystemNumber()+"進制數\n"+b1.getMyNumber()+"轉化爲"+R1+"進制數並保留"+f+"位小數後去除無效位的結果爲:\n"+b3);  
  17.         long c4=System.currentTimeMillis();  
  18.         b4=b2.HexConversion(R1, f);  
  19.         System.out.println("將"+b2.getSystemNumber()+"進制數\n"+b2.getMyNumber()+"轉化爲"+R1+"進制數並保留"+f+"位小數後去除無效位的結果爲:\n"+b4);  
  20.         long c5=System.currentTimeMillis();  
  21.         System.out.println("四次轉換分別耗時爲"+(c2-c1)+"ms,"+(c3-c2)+"ms,"+(c4-c3)+"ms,"+(c5-c4)+"ms");  
  22.     }     
  23. }  



測試結果:

[java] view plain copy
  1. 39進制數  
  2. 1313624242ADAFSFGDRG424242ADAF679707464342424242ADAFS24242ADAFSFGDRG424242ADAFFGDRG142356679707464342424242ADAFSFGDRG67866679707464342424242ADAFSFGDRG96068563556667970746V6679707464342424423536858686242ADAFSFGD69979RG67970746434242427979742ADAFS.FGDRG646676679707464342424242ADAFSFGDRG9707464342424242ADAFSFGDRG342424242ADAFSFGDRG67970746434266797074643426679707464342424242ADAFSFGDRG424242ADAFSFGDRG424242ADAFSFGDRG24242342426679707464342424242ADAFSFGDRG534364547455686679707464342424242ADAFSFGDRG6679707464342424242ADAFSFGDRGDADA6679707464342424242ADAFSFGDRGAFSFS6679707464342424242ADAFSFGDRG轉化爲62進制數並保留348位小數後去除無效位的結果爲:  
  3. CSicxuSbDy6b15mLRWpdQ03beazrJG5zcEBpMTZ7oxowiNnCN2V2M9xDYHbAF9g6yYEPhEPyQi1Jki1eamKZv9ceksCKkZzNjHDFv7wnmlCJSPVJtkFovcB65NUUYnHyMRYOMrt7wpQg1cy9UFqoVJOg6uicQZDDxdsxW7OdFtG60YEkAx3uuL6izr87hebmroc4ZHum8izmVRxylA1mARwFa.OVmjfCSTpwpEPSYDMTLpzKxV1LWaoEOdZV8Q5Ie2y8XeUDJ5M5Yh4QksANCxWcYlDW1v3XpvZ5AXC7XLlR5uyHK63kwPWpwJhLh6nm0ypGg1iwIWo1N7DP6JQEz3cP5kJx90WtGH6BOEmMgsRPC4cOnUYeS6Ckx8KmdNtMl1P2qN6cHsxZFYOgPg3MRHuNVMhuApscNlpkWlM11Yj5X8nAuLW140Pj4PEn5jgktOGO2y20LPgqM77GGz6d0PyF0H3EL7OwAVLVv1ARt4jlKbomwr1rRyqvV975kZtJVatHkNsr8PCLHGz63p59NIQRkXOd6cyROVnwCpRtmBi3dXU4Vlo0Z7  
  4. 39進制數  
  5. 1313624242ADAFSFGDRG424242ADAF679707464342424242ADAFS24242ADAFSFGDRG424242ADAFFGDRG142356679707464342424242ADAFSFGDRG67866679707464342424242ADAFSFGDRG96068563556667970746V6679707464342424423536858686242ADAFSFGD69979RG67970746434242427979742ADAFS.FGDRG646676679707464342424242ADAFSFGDRG9707464342424242ADAFSFGDRG342424242ADAFSFGDRG67970746434266797074643426679707464342424242ADAFSFGDRG424242ADAFSFGDRG424242ADAFSFGDRG24242342426679707464342424242ADAFSFGDRG534364547455686679707464342424242ADAFSFGDRG6679707464342424242ADAFSFGDRGDADA6679707464342424242ADAFSFGDRGAFSFS6679707464342424242ADAFSFGDRG轉化爲2進制數並保留348位小數後去除無效位的結果爲:  
  6. 110101101010110010111000101001101101000100001111010000100111110011011011000111010010000001100101000011100001001100010000111001010100011011101110010111011001011101001110011110100011101010100110111001010011011110011001011111001111000010010000010101110100010010000011111111011100010001110111111111111101110000110010001001110100100001010111100110001101110001001011110000101011000010100110100101111000110111111100110010101111111101011100110100100100101111011010001111001111111010101100100010110100001100101010111101010110100101000100110100011110001011000011110011001010001110000001001101110011011001011100110101011011101110000011010100001011100101111001000110110111010010100101100101011110101010001101100010000000000111100110010111011110010101011011001111100110000100010000011001011110101111001001001011111110110110110110101011100101100011111011011010100001000100100101010100111100111110110001010001000011001011000111111101100111011011110110001101101010000100101000110010100000110011111100001001101000000010101000000010110000001000101111001111111100010100000111110010010100000110011100100111001010001101010111010110100100011011000011100001001100110010010100110001010001011110101111100111110110000001111101110011100110101101101101011110010111100001001000001110100100000001011111100010101110110110.011001010011011010110001001001110110111110110101111110111110010011011101011111000001100101000110110001001011101011100010000101010010110101111011111101111100010100010100010101100001100100111111011110001101111111010111111010011001000110101011101000100111100010111100010110110110100001000001110011110010110110110101110111000100100111111100110010010011  
  7. 62進制數  
  8. CSicxuSbDy6b15mLRWpdQ03beazrJG5zcEBpMTZ7oxowiNnCN2V2M9xDYHbAF9g6yYEPhEPyQi1Jki1eamKZv9ceksCKkZzNjHDFv7wnmlCJSPVJtkFovcB65NUUYnHyMRYOMrt7wpQg1cy9UFqoVJOg6uicQZDDxdsxW7OdFtG60YEkAx3uuL6izr87hebmroc4ZHum8izmVRxylA1mARwFa.OVmjfCSTpwpEPSYDMTLpzKxV1LWaoEOdZV8Q5Ie2y8XeUDJ5M5Yh4QksANCxWcYlDW1v3XpvZ5AXC7XLlR5uyHK63kwPWpwJhLh6nm0ypGg1iwIWo1N7DP6JQEz3cP5kJx90WtGH6BOEmMgsRPC4cOnUYeS6Ckx8KmdNtMl1P2qN6cHsxZFYOgPg3MRHuNVMhuApscNlpkWlM11Yj5X8nAuLW140Pj4PEn5jgktOGO2y20LPgqM77GGz6d0PyF0H3EL7OwAVLVv1ARt4jlKbomwr1rRyqvV975kZtJVatHkNsr8PCLHGz63p59NIQRkXOd6cyROVnwCpRtmBi3dXU4Vlo0Z7轉化爲39進制數並保留348位小數後去除無效位的結果爲:  
  9. 1313624242ADAFSFGDRG424242ADAF679707464342424242ADAFS24242ADAFSFGDRG424242ADAFFGDRG142356679707464342424242ADAFSFGDRG67866679707464342424242ADAFSFGDRG96068563556667970746V6679707464342424423536858686242ADAFSFGD69979RG67970746434242427979742ADAFS.FGDRG646676679707464342424242ADAFSFGDRG9707464342424242ADAFSFGDRG342424242ADAFSFGDRG67970746434266797074643426679707464342424242ADAFSFGDRG424242ADAFSFGDRG424242ADAFSFGDRG24242342426679707464342424242ADAFSFGDRG534364547455686679707464342424242ADAFSFGDRG6679707464342424242ADAFSFGDRGDADA6679707464342424242ADAFSFGDRGAFSFS6679707464342424242ADAFSFGDRF  
  10. 2進制數  
  11. 110101101010110010111000101001101101000100001111010000100111110011011011000111010010000001100101000011100001001100010000111001010100011011101110010111011001011101001110011110100011101010100110111001010011011110011001011111001111000010010000010101110100010010000011111111011100010001110111111111111101110000110010001001110100100001010111100110001101110001001011110000101011000010100110100101111000110111111100110010101111111101011100110100100100101111011010001111001111111010101100100010110100001100101010111101010110100101000100110100011110001011000011110011001010001110000001001101110011011001011100110101011011101110000011010100001011100101111001000110110111010010100101100101011110101010001101100010000000000111100110010111011110010101011011001111100110000100010000011001011110101111001001001011111110110110110110101011100101100011111011011010100001000100100101010100111100111110110001010001000011001011000111111101100111011011110110001101101010000100101000110010100000110011111100001001101000000010101000000010110000001000101111001111111100010100000111110010010100000110011100100111001010001101010111010110100100011011000011100001001100110010010100110001010001011110101111100111110110000001111101110011100110101101101101011110010111100001001000001110100100000001011111100010101110110110.011001010011011010110001001001110110111110110101111110111110010011011101011111000001100101000110110001001011101011100010000101010010110101111011111101111100010100010100010101100001100100111111011110001101111111010111111010011001000110101011101000100111100010111100010110110110100001000001110011110010110110110101110111000100100111111100110010010011轉化爲39進制數並保留348位小數後去除無效位的結果爲:  
  12. 1313624242ADAFSFGDRG424242ADAF679707464342424242ADAFS24242ADAFSFGDRG424242ADAFFGDRG142356679707464342424242ADAFSFGDRG67866679707464342424242ADAFSFGDRG96068563556667970746V6679707464342424423536858686242ADAFSFGD69979RG67970746434242427979742ADAFS.FGDRG646676679707464342424242ADAFSFGDRG9707464342424242ADAFSFGDRG2UXNCMJNcZJJTAYBcNcPCOYPEHSET1EJ9c650HV24PNO1CDYUMXBEVT8P294CL2Lc81MQIRODQD6YUH3HVa7ADOUHW696PF2c0KU8XJJa6WYYASbGYRTUCCVO0BD8AGZEMSW2MWTCI3NbHFZW8GIC0FTRYNV8TCVAQF9N6AZHMDB5N16IWGUPHU812HN7AMT97LIUFX9DEZ5B841I6KMS3JGNMYVF79FXQHK8Y8DJKUUV3AaJVEWS80ZSaC0IKcVCXAaB5I3WBC2KAIGG0AIbR2Z2Ob  
  13. 四次轉換分別耗時爲468ms,169ms,195ms,75ms  



使用php:

<?php
//超大整數(10進制)轉換爲二進制數
$n='12121111111141417908308410289576890247569807456709384756890743906790486790845';
//$n='15';//1111
//$n='257';//100000001
$r='';//結果
while ($n){
  //$n整除2,商$m、餘數$k
  $k=0;
  $m='';
  do{
    $k=$k*10 + substr($n,0,1);
    if ($m!='' || $k>1) $m.=floor($k/2);
    $k=$k % 2;
    $n=substr($n,1);
    //$r=$k . $r;
  }while($n!='');
  //echo "r=$r;m=$m\n";//break;
  //下一輪除法
  $n=$m;
  $r=$k . $r;
}
echo $r;
?>

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章