概述:
实现参与运算的数或者运算结果中,长度最大的一个数的位数,不超过String类型最大长度的大数的四则运算。
实现思路:
加法:模拟笔算的过程,逐位运算;
减法:先比较大小,让较大的数作为被减数(被减数-减数=差),再仿照加法运算;
乘法:和加法类似,逐位运算;
除法(整除):除法比较复杂一点,是用连续相减实现。不过用被除数逐个减除数显然太慢了,我们首先得到被除数和除数相差的位数n,令temp为除数乘以10的n次方,使满足被除数×0.1≤temp≤被除数,用被除数减去temp,然后n--,重新得到temp,重复上面过程,直至n为0;
求余:和整除的思路一样,只是最后返回的值不一样。
public class BigNumber {
private static BigNumber self = new BigNumber();
/**
* add
*/
public String add(String string1, String string2) {
string1 = self.getStandardString(string1);
string2 = self.getStandardString(string2);
int len1 = string1.length();
int len2 = string2.length();
int sumLen = Math.max(len1, len2) + 1;
int[] array1 = new int[sumLen];
int[] array2 = new int[sumLen];
int[] sum = new int[sumLen];
int temp = 0;
// 字符串转数组
for (int i = len1 - 1, j = 0; i >= 0; i--, j++) {
array1[j] = (int) string1.charAt(i) - '0';
}
// 字符串转数组
for (int i = len2 - 1, j = 0; i >= 0; i--, j++) {
array2[j] = (int) string2.charAt(i) - '0';
}
// 求和
for (int i = 0; i < sumLen; i++) {
temp = sum[i] + array1[i] + array2[i];
if (temp >= 10) {
temp = temp - 10;
sum[i + 1] = 1;
}
sum[i] = temp;
}
StringBuilder result = new StringBuilder();
boolean flag = true;
for (int i = sumLen - 1; i >= 0; i--) {
if (flag) {
if (sum[i] == 0) {
continue;
} else {
flag = false;
}
}
result.append(sum[i]);
}
return result.toString();
}
/**
* sub
*/
public String sub(String string1, String string2) {
string1 = self.getStandardString(string1);
string2 = self.getStandardString(string2);
int len1 = string1.length();
int len2 = string2.length();
StringBuilder result = new StringBuilder();
// 将大的字符串放前面
int relation = self.getThen(string1, string2);
if (relation == -1) {
String tempString = string1;
string1 = string2;
string2 = tempString;
result.append("-");
} else if (relation == 0) {
return "0";
}
len1 = string1.length();
len2 = string2.length();
int sumLen = Math.max(len1, len2);
int[] array1 = new int[sumLen];
int[] array2 = new int[sumLen];
int[] sum = new int[sumLen];
int temp = 0;
// 字符串转数组
for (int i = len1 - 1, j = 0; i >= 0; i--, j++) {
array1[j] = (int) string1.charAt(i) - '0';
}
// 字符串转数组
for (int i = len2 - 1, j = 0; i >= 0; i--, j++) {
array2[j] = (int) string2.charAt(i) - '0';
}
// 求差
for (int i = 0; i < sumLen; i++) {
temp = sum[i] + array1[i] - array2[i];
if (temp < 0) {
temp = temp + 10;
sum[i + 1] = -1;
}
sum[i] = temp;
}
boolean flag = true;
for (int i = sumLen - 1; i >= 0; i--) {
if (flag) {
if (sum[i] == 0) {
continue;
} else {
flag = false;
}
}
result.append(sum[i]);
}
return result.toString();
}
/**
* mul
*/
public String mul(String string1, String string2) {
string1 = self.getStandardString(string1);
string2 = self.getStandardString(string2);
int len1 = string1.length();
int len2 = string2.length();
int[] array1 = new int[len1];
int[] array2 = new int[len2];
int[][] sum = new int[len2][len1 + 1];
int temp = 0;
// 字符串转数组
for (int i = len1 - 1, j = 0; i >= 0; i--, j++) {
array1[j] = (int) string1.charAt(i) - '0';
}
// 字符串转数组
for (int i = len2 - 1, j = 0; i >= 0; i--, j++) {
array2[j] = (int) string2.charAt(i) - '0';
}
// 求积
for (int i = 0; i < len2; i++) {
for (int j = 0; j < len1; j++) {
temp = array2[i] * array1[j] + sum[i][j];
sum[i][j] = temp % 10;
sum[i][j + 1] = temp / 10;
}
}
String result = null;
StringBuilder midResult = new StringBuilder();
StringBuilder tempResult;
for (int i = len1; i >= 0; i--) {
midResult.append(sum[0][i]);
}
result = midResult.toString();
if (len2 == 1) {
return self.add(midResult.toString(), "0");
}
for (int i = 1; i < len2; i++) {
tempResult = new StringBuilder();
for (int j = len1; j >= 0; j--) {
tempResult.append(sum[i][j]);
}
for (int k = 0; k < i; k++) {
tempResult.append("0");
}
result = self.add(result, tempResult.toString());
}
return result;
}
/**
* div
*/
public String div(String string1, String string2) throws Exception {
string1 = self.getStandardString(string1);
string2 = self.getStandardString(string2);
if (string2.equals("0")) {
Exception exception = new ArithmeticException();
throw exception;
}
int len1 = string1.length();
int len2 = string2.length();
int relation = self.getThen(string1, string2);
if (relation == -1) {
return "0";
} else if (relation == 0) {
return "1";
}
int distance = len1 - len2;
int count = 0;
StringBuilder midNum;
String midString;
String midResult;
String result = "0";
while (distance >= 0) {
StringBuilder coe = new StringBuilder("1"); // 倍数
for (int i = 0; i < distance; i++) { // *10
coe.append("0");
}
midNum = new StringBuilder();
midNum.append(string2);
for (int i = 0; i < distance; i++) { // *10
midNum.append("0");
}
midString = midNum.toString(); // 减数
if (self.getThen(midString, string1) == 1) {
distance--;
continue;
}
count = 0;
while (self.getThen(midString, string1) < 1) {
string1 = self.sub(string1, midString);
count++;
}
midResult = self.mul(coe.toString(), String.valueOf(count));
result = self.add(result, midResult);
distance--;
}
return result;
}
/**
* mod
*/
public String mod(String string1, String string2) throws Exception {
string1 = self.getStandardString(string1);
string2 = self.getStandardString(string2);
if (string2.equals("0")) {
Exception exception = new ArithmeticException();
throw exception;
}
int len1 = string1.length();
int len2 = string2.length();
int relation = self.getThen(string1, string2);
if (relation == -1) {
return string1;
} else if (relation == 0) {
return "0";
}
int distance = len1 - len2;
StringBuilder midNum;
String midString;
String result = "0";
while (distance >= 0) {
StringBuilder coe = new StringBuilder("1"); // 倍数
for (int i = 0; i < distance; i++) { // *10
coe.append("0");
}
midNum = new StringBuilder();
midNum.append(string2);
for (int i = 0; i < distance; i++) { // *10
midNum.append("0");
}
midString = midNum.toString(); // 减数
if (self.getThen(midString, string1) == 1) {
distance--;
continue;
}
while (self.getThen(midString, string1) < 1) {
string1 = self.sub(string1, midString);
}
result = string1;
distance--;
}
return result;
}
/**
* get relation ; str1 > str2 -> 1 ; str1 = str2 -> 0 ; str1 < str2 -> -1 ;
*/
private int getThen(String string1, String string2) {
string1 = self.getStandardString(string1);
string2 = self.getStandardString(string2);
int len1 = string1.length();
int len2 = string2.length();
if (len1 < len2) {
return -1;
} else if (len1 > len2) {
return 1;
} else if (len1 == len2) {
for (int i = 0; i < len1; i++) {
if (string1.charAt(i) == string2.charAt(i)) {
continue;
} else if (string1.charAt(i) > string2.charAt(i)) {
return 1;
} else
return -1;
}
}
return 0;
}
/**
* return standard string
*/
private String getStandardString(String string) {
string = string.trim();
StringBuilder stringBuilder = new StringBuilder();
char singleChar;
boolean flag = true;
// 剥离非数字字符
for (int index = 0; index < string.length(); index++) {
singleChar = string.charAt(index);
if (singleChar <= '9' && singleChar >= '0') {
stringBuilder.append(singleChar);
}
}
string = stringBuilder.toString();
stringBuilder = new StringBuilder();
// 剥离开头的数字0
for (int index = 0; index < string.length(); index++) {
singleChar = string.charAt(index);
if (flag) {
if (singleChar == '0') {
continue;
} else {
flag = false;
}
}
stringBuilder.append(singleChar);
}
String result = stringBuilder.toString();
if (result == null || result.length() == 0) {
return "0";
}
return result;
}
}