您的位置:首页 > 其它

大数字运算

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

具体实现代码如下:

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;
}
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: