对于大数字的运算

来源:互联网 发布:香港有线电视台软件 编辑:程序博客网 时间:2024/05/01 07:55


说明:由于在各种语言中各种整型数据是会受到各种的规范(如在java的整型中byte只有分配一个字节8位,最大的long类型有8个字节也就是说最大能表示2的64次的数)那么在java中对于超过2的64次方的整数进行运算时该怎么办?(通常对这个数被称为大数)

    解法:对与一个整数来说,既然不能用一个类型来表示,那么只能用一个整型的数组来表示来。对与即将操作的数进行分段表示。此处为了方便表示以及能够表达我想表达的内容,这里用int型的数组,对一个不超过16位的数进行加、减、乘(由于乘法对于数的位数影响这里最大支持8位)除(对于两个大数来说个人感觉除法没什么用处,毕竟除法会影响精度,两个大数相除结果一定很小。  这里只写了一个大数被一个小数除的除法)。




+、-、*、/


   如图:对一个16位的数进行分割,每4位一组存放在int[] A和B中将结果放在C中。

    注意:由于规定每个数组元素只能存放一个4位数的整数,在进行运算时应该考虑进位和借位的问题,由于在不同运算下产生的借位或进位不同,故在每个方法里用不同的解决方法。

    加法:

addcheck():解决进位问题

public int addcheck(int a, int b) {int flag;if (a + b > 10000)     //由于规定了是一个4位数故大于10000就是进位了flag = 1;elseflag = 0;return flag;}

这里不是用boolean解决是因为个人感觉返回int的话能直接用了。。。。。

add():解决方法

public void add() {int flag = 0;           //flag为进位for (int i = 3; i >= 0; i--) {int d = addcheck(a[i], b[i]);c[i] = a[i] + b[i] - d * 10000 + flag;flag = d;}}
对与为什么不直接把进位赋给flag:flag是低位给高位的标志,若当前已经产生了进位,那么应该先考虑把高位给去掉,那么就有这个d存在的必要了。

    减法:

subcheck():

public int subcheck(int a, int b) {if (a - b < 0)return -1;return 0;}

sub():

public void sub() {int flag = 0;boolean temp = true;//考虑到有可能b存放到数比a大先检测如果是b大那么将a b互换后在进行减法用temp记录正负for (int i = 0; i < 4; i++) {if (a[i] != 0 && b[i] == 0) {break;}if (a[i] < b[i]) {c = a;a = b;b = c;temp = false;break;}}for (int i = 3; i >= 0; i--) {int d = subcheck(a[i], b[i]);c[i] = (-d) * 10000 + a[i] - b[i] +flag;flag = d;}System.out.print(temp ? "" : "-");}
这里的d是和加法一样的考虑。

    乘法:

int[] mulpre():两个4位的整数相乘会最大会产生一个8位的数,考虑到最大能表示4位,故先写一个方法返回一个数组,数组里面有两个元素:前4位和后4位。

public int[] mulpre(int a,int b){int flag=10000;    //表示现在b的位数10000是4位1000是3位int tempa[]={0,0};int tempb;for(int i=1;i<5;i++){tempb=b%10;  //取得b中最后的一个数b=b/10;      //将b前3位给btempa[0]+=a*tempb/flag;   //计算前4位tempa[1]+=a*tempb%flag*(10000/flag); //计算后4位flag/=10;}tempa[0]+=tempa[1]/10000;tempa[1]%=10000;return tempa;}

for循环:求数组内两个元素的大小的:比如 1234*5678,先拿8和1234乘取后4位为tempa[1],剩下的是tempa[0],接下来就是7和1234乘取后3位乘10后和原来的tempa[1]相加,剩下的和tempa[0]相加,同理那5和6乘,得到一个包含有两个4位数的数组。

mul():

public void mul(){int flag;int[] temp1=mulpre(a[3], b[3]);int[] temp2=mulpre(a[2], b[2]);int[] temp3=mulpre(a[3], b[2]);int[] temp4=mulpre(a[2], b[3]);c[3]=temp1[1];c[2]=temp1[0]+temp3[1]+temp4[1];flag=c[2]/10000;c[2]=c[2]%10000;c[1]=temp3[0]+temp4[0]+temp2[1]+flag;flag=c[1]/10000;c[1]=c[1]%10000;c[0]=temp2[0];}
这里表示了两个8位数的乘法(两个8位数分别放在a和b的后两个数组单位中)结果c[0]中应该是a[3]*b[3]的前4位,c[1]是a[3]*b[3]后4位 a[3]*b[4]、a[4]*b[3]的前4位之和,c[2]、c[3]都差不多,当然还要考虑进位的问题。

    由于除法只要将c[i]中的数除,将余数保存,在c[i+1]中使用就可以解决。

div():

public void div(int div){int flag=0;for(int i=0;i<4;i++){a[i]+=flag*10000;c[i]=a[i]/div;flag=a[i]%div;}}

全部的代码:

public class BigInteger {public int[] a = new int[4];public int[] b = new int[4];public int[] c = new int[4];public BigInteger(String c, String d) {a = prepare(c);b = prepare(d);}    //该方法用于切割支付串数组  大数不能被表示嘛  只能用字符串表示了public int[] prepare(String s) {int[] a = new int[4];int l = s.length();for (int j = l, i = 3; j > 0 && i >= 0; j -= 4, i--) {if (j > 3) {String tem = s.substring(j - 4, j);a[i] = Integer.parseInt(tem);} else {String tem = s.substring(0, j);a[i] = Integer.parseInt(tem);}}return a;}public void out() {for (int i = 0; i < 4; i++)if (c[i] != 0)System.out.print(c[i]);System.out.println();}public int addcheck(int a, int b) {int flag;if (a + b > 10000)     //由于规定了是一个4位数故大于10000就是进位了flag = 1;elseflag = 0;return flag;}public void add() {int flag = 0;           //flag为进位for (int i = 3; i >= 0; i--) {int d = addcheck(a[i], b[i]);c[i] = a[i] + b[i] - d * 10000 + flag;flag = d;}out();}public int subcheck(int a, int b) {if (a - b < 0)return -1;return 0;}public void sub() {int flag = 0;boolean temp = true;//考虑到有可能b存放到数比a大先检测如果是b大那么将a b互换后在进行减法用temp记录正负for (int i = 0; i < 4; i++) {if (a[i] != 0 && b[i] == 0) {break;}if (a[i] < b[i]) {c = a;a = b;b = c;temp = false;break;}}for (int i = 3; i >= 0; i--) {int d = subcheck(a[i], b[i]);//System.out.println(a[i] + " " + b[i]);c[i] = (-d) * 10000 + a[i] - b[i] + flag;//System.out.println(c[i]);flag = d;}System.out.print(temp ? "" : "-");out();}public int[] mulpre(int a,int b){int flag=10000;int tempa[]={0,0};int tempb;for(int i=1;i<5;i++){tempb=b%10;//System.out.println(tempb);b=b/10;tempa[0]+=a*tempb/flag;//System.out.println(tempa[0]);tempa[1]+=a*tempb%flag*(10000/flag);flag/=10;}tempa[0]+=tempa[1]/10000;tempa[1]%=10000;return tempa;}public void mul(){int flag;int[] temp1=mulpre(a[3], b[3]);int[] temp2=mulpre(a[2], b[2]);int[] temp3=mulpre(a[3], b[2]);int[] temp4=mulpre(a[2], b[3]);c[3]=temp1[1];c[2]=temp1[0]+temp3[1]+temp4[1];flag=c[2]/10000;c[2]=c[2]%10000;c[1]=temp3[0]+temp4[0]+temp2[1]+flag;flag=c[1]/10000;c[1]=c[1]%10000;c[0]=temp2[0];out();}public void div(int div){int flag=0;for(int i=0;i<4;i++){a[i]+=flag*10000;c[i]=a[i]/div;flag=a[i]%div;}out();}public static void main(String[] args) {BigInteger bi = new BigInteger("1076234", "92343241");bi.add();bi.sub();bi.mul();bi.div(2);}}
这是在这儿的第一篇,有什么表达不清楚的可以找我哈,有什么错误的也请多多包涵。

0 0
原创粉丝点击