一、功能
使用int[],实现大数的加减乘数运算
二、注意
完整的大数运算代码找不到了,这是从其他算法里摘出来的大数运算部分,所以可能运行不了,但是可以提供思路
三、代码实现
public static int MAX_DECIMAL_DIGIT = 9999;
/**
* 判断大小
*
* @param a
* @param b
* @return
*/
public static int judgeSize(int[] a, int[] b) {
int i, j;
int flag = 0;//flag = 0代表相等
int len1, len2;
for (i = 0; i < a.length; i++) {
if (a[i] != 0)
break;
}
len1 = a.length - i;//防止a的前i位是0从而影响判断,len1是去掉0后的实际长度
int[] temp_a = new int[len1];
System.arraycopy(a, i, temp_a, 0, len1);
if (temp_a.length == 0)
temp_a = new int[]{0};
for (j = 0; j < b.length; j++) {
if (b[j] != 0)
break;
}
len2 = b.length - j;
int[] temp_b = new int[len2];
System.arraycopy(b, j, temp_b, 0, len2);
if (temp_b.length == 0)
temp_b = new int[]{0};
if (temp_a[0] >= 0 && temp_b[0] >= 0) {
if (len1 < len2) {
flag = -1;//a<b返回-1
} else if (len1 > len2) {
flag = 1;
} else {//长度相等时,逐位比较
for (i = 0; i < temp_a.length; i++) {
if (temp_a[i] < temp_b[i]) {
flag = -1;
break;
}
if (temp_a[i] > temp_b[i]) {
flag = 1;
break;
}
}
}
}
if (temp_a[0] < 0 && temp_b[0] < 0) {
if (len1 > len2) {
flag = -1;
} else if (len1 < len2) {
flag = 1;
} else if (len1 == len2 && temp_a[0] == temp_b[0]) {//长度相等时,逐位比较
for (i = 1; i < temp_a.length; i++) {
if (temp_a[i] > temp_b[i]) {
flag = -1;
break;
}
if (temp_a[i] < temp_b[i]) {
flag = 1;
break;
}
}
} else if (len1 == len2 && temp_a[0] > temp_b[0]) {
flag = 1;
} else {
flag = -1;
}
}
if (temp_a[0] < 0 && temp_b[0] >= 0) {
flag = -1;
}
if (temp_a[0] >= 0 && temp_b[0] < 0) {
flag = 1;
}
return flag;
}
/**
* 加法
*
* @param a
* @param b
* @return
*/
public static int[] add(int[] a, int[] b) {
int[] temp;
int[] max;
int[] min;
int[] result;
int[] result2;
int i;
int gap;
int base = 0;//base记录进位
int flag = 0;
int[] temp_a = new int[a.length];
System.arraycopy(a, 0, temp_a, 0, a.length);
int[] temp_b = new int[b.length];
System.arraycopy(b, 0, temp_b, 0, b.length);
if ((temp_a[0] >= 0 && temp_b[0] >= 0) || (temp_a[0] < 0 && temp_b[0] < 0)) {
if (temp_a[0] < 0 && temp_b[0] < 0)
flag = 1;
temp_a[0] = Math.abs(temp_a[0]);
temp_b[0] = Math.abs(temp_b[0]);
if (temp_a.length < temp_b.length) {
temp = temp_a;
temp_a = temp_b;
temp_b = temp;
}
max = new int[temp_a.length];
min = new int[max.length];
result = new int[max.length];
gap = temp_a.length - temp_b.length;
System.arraycopy(temp_a, 0, max, 0, temp_a.length);
System.arraycopy(temp_b, 0, min, gap, temp_b.length);
for (i = max.length - 1; i >= 0; i--) {
result[i] = max[i] + min[i] + base;
base = 0;
if (result[i] >= 10) {
result[i] = result[i] - 10;
base = 1;
}
}
//如果最后结束的时候进位base==1,说明最终结果的位数比max多1,且第一位是1
if (base == 1) {
result2 = new int[result.length + 1];
result2[0] = 1;
System.arraycopy(result, 0, result2, 1, result.length);
if (flag == 1)
result2[0] = -result2[0];
return result2;
} else {
if (flag == 1)
result[0] = -result[0];
return result;
}
} else if (temp_a[0] >= 0 && temp_b[0] < 0) {
temp_b[0] = Math.abs(temp_b[0]);
result = subtract_negative(temp_a, temp_b);
} else {
temp_a[0] = Math.abs(temp_a[0]);
result = subtract_negative(temp_b, temp_a);
}
return result;
}
/**
* 减法。计算不出负数
*
* @param a
* @param b
* @return
*/
public static int[] subtract(int[] a, int[] b) {
int i, j;
int len1, len2;
int[] temp;
int[] max;
int[] min;
int[] result;
int gap;
int base = 0;//base记录进位
for (i = 0; i < a.length; i++) {
if (a[i] != 0)
break;
}
len1 = a.length - i;//防止a的前i位是0从而影响判断,len1是去掉0后的实际长度
int[] temp_a = new int[len1];
System.arraycopy(a, i, temp_a, 0, len1);
for (j = 0; j < b.length; j++) {
if (b[j] != 0)
break;
}
len2 = b.length - j;
int[] temp_b = new int[len2];
System.arraycopy(b, j, temp_b, 0, len2);
if (len1 < len2) {
temp = temp_a;
temp_a = temp_b;
temp_b = temp;
}
if (len1 == len2) {
for (i = 0; i < temp_a.length; i++) {
if (temp_a[i] < temp_b[i]) {
temp = temp_a;
temp_a = temp_b;
temp_b = temp;
break;
}
if (temp_a[i] > temp_b[i]) {
break;
}
}
}
if (temp_b.length == 0)
temp_b = new int[1];
max = new int[temp_a.length];
min = new int[max.length];
result = new int[max.length];
gap = temp_a.length - temp_b.length;
System.arraycopy(temp_a, 0, max, 0, temp_a.length);
System.arraycopy(temp_b, 0, min, gap, temp_b.length);
for (i = max.length - 1; i >= 0; i--) {
result[i] = max[i] - min[i] - base;
base = 0;
if (result[i] < 0) {
result[i] = result[i] + 10;
base = 1;
}
}
for (i = 0; i < result.length; i++) {
if (result[i] != 0)
break;
}
if (i == result.length)
return new int[]{0};
int[] result2 = new int[result.length - i];
for (j = 0; i < result.length; j++, i++)
result2[j] = result[i];
return result2;
}
/**
* 减法。负数间计算
*
* @param a
* @param b
* @return
*/
public static int[] subtract_negative(int[] a, int[] b) {
int i, j;
int len1, len2;
int[] temp;
int[] t;
int flag = 0;
for (i = 0; i < a.length; i++) {
if (a[i] != 0)
break;
}
len1 = a.length - i;//防止a的前i位是0从而影响判断,len1是去掉0后的实际长度
int[] temp_a = new int[len1];
System.arraycopy(a, i, temp_a, 0, len1);
if (temp_a.length == 0)
temp_a = new int[]{0};
for (j = 0; j < b.length; j++) {
if (b[j] != 0)
break;
}
len2 = b.length - j;
int[] temp_b = new int[len2];
System.arraycopy(b, j, temp_b, 0, len2);
if (temp_b.length == 0)
temp_b = new int[]{0};
if (temp_a[0] >= 0 && temp_b[0] < 0) {
temp_b[0] = -temp_b[0];
return add(temp_a, temp_b);
}
if (temp_a[0] < 0 && temp_b[0] >= 0) {
temp_a[0] = -temp_a[0];
t = add(temp_a, temp_b);
t[0] = -t[0];
return t;
}
if (temp_a[0] >= 0 && temp_b[0] >= 0) {
if (len1 < len2) {
t = subtract(temp_a, temp_b);
t[0] = -t[0];
return t;
}
if (len1 == len2) {
for (i = 0; i < temp_a.length; i++) {
if (temp_a[i] < temp_b[i]) {
t = subtract(temp_a, temp_b);
t[0] = -t[0];
return t;
}
if (temp_a[i] > temp_b[i]) {
return subtract(temp_a, temp_b);
}
}
if (i == temp_a.length)
return new int[]{0};
}
if (len1 > len2) {
return subtract(temp_a, temp_b);
}
}
if (temp_a[0] < 0 && temp_b[0] < 0) {
temp_a[0] = -temp_a[0];
temp_b[0] = -temp_b[0];
if (len1 < len2 || (len1 == len2 && temp_a[0] < temp_b[0])) {
return subtract(temp_a, temp_b);
}
if (len1 > len2 || (len1 == len2 && temp_a[0] > temp_b[0])) {
t = subtract(temp_a, temp_b);
t[0] = -t[0];
return t;
}
if (len1 == len2) {
for (i = 1; i < temp_a.length; i++) {
if (temp_a[i] > temp_b[i]) {
t = subtract(temp_a, temp_b);
t[0] = -t[0];
return t;
}
if (temp_a[i] < temp_b[i]) {
return subtract(temp_a, temp_b);
}
}
}
}
return new int[]{0};
}
/**
* 乘法
*
* @param a
* @param b
* @return
*/
public static int[] multi(int[] a, int[] b) {
int t;
if (a.length == 0)
a = new int[]{0};
if (b.length == 0)
b = new int[]{0};
int[] temp_a = new int[a.length];
int[] temp_b = new int[b.length];
System.arraycopy(a, 0, temp_a, 0, a.length);
System.arraycopy(b, 0, temp_b, 0, b.length);
temp_a[0] = Math.abs(temp_a[0]);
temp_b[0] = Math.abs(temp_b[0]);
for (int i = 0; i < temp_a.length / 2; i++) {
t = temp_a[i];
temp_a[i] = temp_a[temp_a.length - 1 - i];
temp_a[temp_a.length - 1 - i] = t;
}
for (int i = 0; i < temp_b.length / 2; i++) {
t = temp_b[i];
temp_b[i] = temp_b[temp_b.length - 1 - i];
temp_b[temp_b.length - 1 - i] = t;
}
//预先声明一个数组,用来存放各个位数相乘的结果(类似于列竖式)
int len = temp_a.length + temp_b.length;
int[] array = new int[len];
//m位数和n位数相乘,得到的结果的位数只能是m+n-1或者m+n。
//把m+n位设置为-1,用来标记最终结果到底是多少位。
array[len - 1] = -1;
//模拟竖式计算
int base = 0;//存储进位
int temp;
for (int i = 0, j; i < temp_b.length; i++) {
base = 0; //进位归位
for (j = 0; j < temp_a.length; j++) {
temp = (temp_b[i]) * (temp_a[j]) + base + array[i + j];
array[i + j] = temp % 10;
base = temp / 10;
}
if (base != 0)
array[i + j] = base;
}
StringBuffer str = arrayFormat(array);
char[] nums = str.toString().toCharArray();
int[] result = new int[nums.length];
for (int i = 0; i < result.length; i++) {
result[i] = nums[i] - 48;
}
if ((a[0] >= 0 && b[0] >= 0) || (a[0] < 0 && b[0] < 0))
return result;
else
result[0] = -result[0];
return result;
}
/**
* 和乘法配合用
*
* @param array
* @return
*/
public static StringBuffer arrayFormat(int[] array) {
StringBuffer buffer = new StringBuffer();
for (int i = 0; i < array.length - 1; i++) {
buffer.append(array[i]);
}
if (array[array.length - 1] != -1)
buffer.append(array[array.length - 1]);
return buffer.reverse();
}
/**
* 除法
*
* @param a
* @param b
* @return
*/
public static int[] divide(int[] a, int[] b) {
int flag_a = 0;
int flag_b = 0;
if (a[0] < 0) {
a[0] = -a[0];
flag_a = 1;
}
if (b[0] < 0) {
b[0] = -b[0];
flag_b = 1;
}
int i, j, k;
int[] diff = new int[b.length - 1];
int[] t1 = new int[b.length];
int[] temp = new int[a.length];
System.arraycopy(a, 0, temp, 0, a.length);
int[] result = new int[a.length];
if (judgeSize(a, b) == -1)
return new int[]{0};
if (Arrays.equals(subtract(a, b), new int[]{0})) {
return new int[]{1};
}
for (k = 0; k < b.length - 1; k++) {
result[k] = 0;
}
for (j = k; j < a.length; j++) {
int len1 = temp.length;
int len2 = diff.length + 1;
System.arraycopy(temp, 0, t1, 0, len2);
while (judgeSize(t1, b) == -1) {
result[j] = 0;
j++;
if (temp.length < len2 + 1)
len2 = temp.length - 1;
t1 = new int[len2 + 1];
System.arraycopy(temp, 0, t1, 0, len2 + 1);
if (j == a.length) {
break;
}
len2++;
}
if (j == a.length)
break;
for (i = 1; i <= 9; i++) {
if ((judgeSize(multi(b, new int[]{i}), t1) == -1 || judgeSize(multi(b, new int[]{i}), t1) == 0) && judgeSize(multi(b, new int[]{i + 1}), t1) == 1) {
result[j] = i;
if (judgeSize(multi(b, new int[]{i}), t1) == 0)
diff = new int[0];
else
diff = subtract(t1, multi(b, new int[]{i}));
break;
}
}
int[] t2 = new int[len1 - t1.length + diff.length];
System.arraycopy(diff, 0, t2, 0, diff.length);
System.arraycopy(temp, t1.length, t2, diff.length, len1 - t1.length);
temp = new int[t2.length];//temp是后面的数
System.arraycopy(t2, 0, temp, 0, t2.length);
t1 = new int[diff.length + 1];//t1是差+后面数的第一位
}
for (i = 0; i < result.length; i++) {
if (result[i] != 0) {
break;
}
}
int[] result2 = new int[result.length - i];
System.arraycopy(result, i, result2, 0, result.length - i);
if ((flag_a == 0 && flag_b == 0) || (flag_a == 1 && flag_b == 1)) {
if (flag_a == 1 && flag_b == 1) {
a[0] = -a[0];
b[0] = -b[0];
}
return result2;
} else if (flag_a == 0 && flag_b == 1) {
b[0] = -b[0];
result2[0] = -result2[0];
return result2;
} else {
a[0] = -a[0];
result2[0] = -result2[0];
return result2;
}
}
/**
* 求余
*
* @param a
* @param b
* @return
*/
public static int[] mod(int[] a, int[] b) {
int[] divide_result = divide(a, b);
int[] multi_result = multi(b, divide_result);
int[] result = subtract(a, multi_result);
return result;
}
/**
* 幂运算
*
* @param a
* @param b
* @return
*/
public static int[] pow(int[] a, int[] b) {
int[] t = a;
int[] result = new int[MAX_DECIMAL_DIGIT];//2的1024次方有309位,所以这个二进制转十进制不可能超过350位
if (judgeSize(b, new int[]{0}) == 0) {
return new int[]{1};
} else if (judgeSize(b, new int[]{1}) == 0)
return a;
else {
for (int[] i = new int[]{1}; judgeSize(i, b) == -1; i = add(i, new int[]{1})) {
result = multi(a, t);
a = result;
}
return result;
}
}