对于大数字的运算
来源:互联网 发布:香港有线电视台软件 编辑:程序博客网 时间: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);}}这是在这儿的第一篇,有什么表达不清楚的可以找我哈,有什么错误的也请多多包涵。
- 对于大数字的运算
- 高精度的大数字运算
- 有关大数字运算的讨论
- java实现大数字的运算
- 华为上机练习题--大数字的运算
- Java 高精度的大数字运算
- 大数字运算
- java 大数字运算结果的显示问题
- 对于数字的各种验证
- 数字的运算
- 怎么用BigDecimal实现大数字运算?
- 堆栈集合做大数字运算
- 对于大并发的思考
- 对于大数据的理解
- javascript 处理大数字的解决方式(仅仅适合于加法减法运算)
- 达内第15天培训知识总结,关于大数字的精确浮点运算以及linkList<>用法
- java对于浮点运算的bug
- linux kernel对于浮点运算的支持
- Asterisk呼叫中心之freepbx安装(五)
- Error #2044: 未处理的 ioError:。 text=Error #2032
- Mean Shift 概述
- Linux常用命令
- iOS内存管理学习心得
- 对于大数字的运算
- boa服务器在S3C2410开发板上移植
- 在线知识库
- 电脑出现 远程计算机或者设备不受连接
- opencv4-highgui之视频的输入和输出以及滚动条
- [ASP.NET MVC 大牛之路]02 - C#高级知识点概要(1) - 委托和事件
- 串口通讯数据处理算法分析与实现
- 设置IP
- pyodbc数据库连接sqlserver数据库