说明:由于在各种语言中各种整型数据是会受到各种的规范(如在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;
else
flag = 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位给b
tempa[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;
else
flag = 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);
}
}
这是在这儿的第一篇,有什么表达不清楚的可以找我哈,有什么错误的也请多多包涵。