大数字运算
2015-11-10 14:44
495 查看
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
具体实现代码如下:
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; } } }
相关文章推荐
- [Unity热更新]lua基础(二)
- mysql读写分离
- Redis编程实践【pub/sub】
- 字符编码
- 【数据结构】循环链表的建立与输出
- C/C++ Volatile关键词深度剖析
- C++/C#结构体转化-二维数组-bytes To Strings
- jquery 对select option 增删改查
- CocoaPods:管理Objective-c 程序中各种第三方开源库关联
- HTML5 LocalStorage本地存储和sessionStorage使用
- OC-RunTime-Method Swizzling
- lvs+keepalived
- HDU 5124 lines
- Learning Bluemix 微信公众号
- CDC双缓冲绘图
- Confluence 用户指南
- 正则
- prop(Property)和attr(attribute)用法区别
- iOS html中Cookie的存取
- boost 多线程