大数字运算

1.使用java中的BigInteger或BigDecimal类
2.自己实现
– 1.大数字加法:将加数和被加数按数n分组,然后每组进行相加,当某组数超过n个数字时,向前进1
如:123456+456789,三个数分一组,则分为123 456+456
789,789+456=1245,123+456=579,由于789+456>1000,因此,向前进1,则低位为245,高位为579+1=580,因此,结果为580245
– 2.大数字减法:将减数和被减数按数n分组,从低位组到高位组逐一相减,当某个组相加为负数时,向前进-1,并加上10的n次幂 如:789456-456789,三个数分一组,则分为789-456=333,456-789=-333,由于低组相减为-333,则向前进-1,并加上1000(10^3)为-333+1000=667,高位为333-1=332,因此,结果为332667
– 3.大数字乘法:将乘数和被乘数各分成两组,然后低位低位,高位低位+低位高位+进位(高位和低位分别来自与不同组),高位高位+进位 如,1234*5678,各分成两组然后求出各个组数
值,34*78=2652,12*78+34*56=2840,12*56=672,低位2652进位26,留下52,2840+26=2866,进位28留下66,672+28=700,进位7,留下00,则结果为7006652
– 4.大数字除法:使用反复相减法,想将除数按照一定的倍数扩张,然后相减,直到不能减,再收缩一个倍数,继续前面步骤 如:12345/123,先123*100=12300,12345/12300=1 余数:45,再45/1230=0 余数:45
最后45/123=0 余数:45,因此,结果为100 余数:45

具体实现代码如下:

import java.io.*;
import java.util.*;
class test  
{

    public static void main (String[] args) throws java.lang.Exception
    {
        String m1="123,456,789";
        String m2="789";
        String sz1[] = m1.split(",");
        String sz2[] = m2.split(",");
        int maxLength= sz1.length>sz2.length?sz1.length:sz2.length;//最大分组数
        int num1[],num2[];
        num1 = new int[maxLength];num2=new int[maxLength];
        transform(sz1,num1);transform(sz2,num2);
        System.out.println("加法:"+add(num1,num2,1000,12));
        System.out.println("减法:"+subtract(num1,num2,1000));
        System.out.println("乘法:"+mutiply(num1,num2));
        test2();
    }
    //除法
    public static void test2(){
        String m1="123,456,789";
        String m2="789";
        String sz1[] = m1.split(",");
        String sz2[] = m2.split(",");
        int maxLength= sz1.length>sz2.length?sz1.length:sz2.length;//最大分组数
        int num1[],num2[];
        num1 = new int[maxLength];num2=new int[maxLength];
        transform(sz1,num1);transform(sz2,num2);
        System.out.println("除法:"+divide(num1,num2,1000,3));
    }
    //字符数组转化数字数组
    public static void transform(String[] d,int[] m){
        for(int i=m.length-1,j=d.length-1;j>=0;--i,--j)
            m[i]=Integer.valueOf(d[j]);
    }
    //大数字加
    public static String add(int[] num1,int[] num2,int count,int maxNum){
        int carry=0;//进位
        int rt[] = new int[maxNum];//存储计算结果,最大不能多过maxNum位数组
        for(int i=num1.length-1,j=maxNum-1;i>=0&&maxNum>=0;--i,--j){
            rt[j] = (num1[i]+num2[i]+carry)%count;
            carry = (num1[i]+num2[i]+carry)/count;
        }
        if(num1.length<count)rt[num1.length]=carry;//超过加数最大位数时,需要额外保存进位
        String rString = "";
        for(int j=0;j<maxNum;++j)rString +=rt[j]==0?"000":String.valueOf(rt[j]);
        return rString;
    }
    //减法
    public static String subtract(int num1[],int num2[],int count){
        int rt[] = new int[num1.length];//存储计算结果
        int carry =0;//当减数大于被减数时,进位为-1
        for(int i=num1.length-1;i>=0;--i){
            rt[i] = num1[i]-num2[i]+carry;
            if(rt[i]<0){
                rt[i]+=count;
                carry=-1;
            }else carry=0;
        }
        String rString = "";
        for(int j=0;j<num1.length;++j)rString +=rt[j]==0?"000":String.valueOf(rt[j]);
        return rString;
    }
    //乘法
    public static String mutiply(int num1[],int num2[]){
        int carry=0;//进位
        int rt[] = new int[4];//存储计算结果,最大不能多过maxNum位数组
        String s1="",s2="";
        s1=toString(num1);
        s2=toString(num2);
        int countNum = s1.length()%2==0?s1.length()/2:s1.length()/2;
        int[] num3=new int[2],num4=new int[2];
        num3[0]=Integer.valueOf(s1.substring(0,countNum));
        num3[1]=Integer.valueOf(s1.substring(countNum,s1.length()));
        num4[0]=Integer.valueOf(s2.substring(0,countNum));
        num4[1]=Integer.valueOf(s2.substring(countNum,s2.length()));
        int j=(int)Math.pow(10,s1.length()-countNum);
        rt[3] = num3[1]*num4[1]%j;
        carry = num3[1]*num4[1]/j;
        rt[2] = (num3[0]*num4[1]+num3[1]*num4[0]+carry)%j;
        carry = (num3[0]*num4[1]+num3[1]*num4[0]+carry)/j;
        rt[1] = (num3[0]*num4[0]+carry)%j;
        carry = (num3[0]*num4[0]+carry)/j;
        rt[0] = carry;
        String rString = "";
        for(int i=0;i<rt.length;++i){
            if(rt[i]<10) rString+="00"+rt[i];
            else if(rt[i]<100)rString+="0"+rt[i];
            else rString+=""+rt[i];
        }
        return rString;
    }
    //数组转化成字符串
    public static String toString(int[] rt){
        String rString="";
        for(int i=0;i<rt.length;++i){
            if(rt[i]<10) rString+="00"+rt[i];
            else if(rt[i]<100)rString+="0"+rt[i];
            else rString+=""+rt[i];
        }
        return rString;
    }
    //除法
    public static String divide(int[] num1,int num2[],int count,int countNum){
        int num1l=numLength(num1,countNum),num2l=numLength(num2,countNum);
        if(num1l<num2l)return toString(num1);
        carry(num2,count,num1l-num2l);
        StringBuilder ys=new StringBuilder();
       // String d=divide1(num1,num2,num1l-num2l,count,ys);
       return divide1(num1,num2,num1l-num2l,count,ys)+" 余数:"+ys;
    }
    //计算总数字长度
    public static int numLength(int[] num,int countNum){
        for(int i=0;i<num.length;++i){
            if(num[i]!=0){
                int length=i*countNum+(num[i]<10?2:num[i]<100?1:0);
                return num.length*countNum-length;
            }
        }
        return 0;
    }
    //递归计算减
    public static String divide1(int[] num1,int num2[],int layer,int count,StringBuilder ys){
        if(layer==-1) {
            ys.append(toString(num1));
            return "";
        }
        int carry=0;
        int sum=0;
        while(carry==0){
            carry=0;
            int[] tem=Arrays.copyOf(num1,num1.length);
            for(int i=tem.length-1;i>=0;--i){
                tem[i] = num1[i]-num2[i]+carry;
                if(tem[i]<0){
                    if(i!=0)tem[i]+=count;
                    carry=-1;
                }else carry=0;
            }

            if(carry==0){
                num1=tem;
                ++sum;
            }
        }
        //向右移1位
        int temCarry=0;
         for(int i=0;i<num2.length;++i){
            num2[i]=num2[i]+temCarry*count;
            temCarry = num2[i]%10;
            num2[i]/=10;
         }
        return sum+divide1(num1,num2,--layer,count,ys);
    }
    //进位
    public static void carry(int num[],int count,int carryNum){
        int carry=0;
        while(carryNum!=0){
            for(int i=num.length-1;i>=0;--i){
                num[i]=num[i]*10+carry;
                carry=num[i]/count;
                num[i] %= count; 
            }
            if(carryNum<0)++carryNum;
            else if(carryNum>0)--carryNum;
        }
    }

}
点赞