场景
当参加运算的数字是超过long型长度的数据,以至于只能用string字符串来存储,这时候加减乘除的运算已经不能用了。
对于这种问题Java提供了一个BigInteger类,可以用来存储,并有对应的加减乘除的方法,要求两个操作数都必须是BIgInteger型。可以解决问题。
这里从模拟计算机的内部实现解读来解决问题。
这个时候就可以像小时候列竖式来计算一样,一位一位的计算,或进位或借位,模拟计算的过程。将整个的计算拆解成一个个小的计算过程。
加法
同号相加,完成后打印符号就可以。这里做的是正数相加未做判断,若要判断符号加几行代码就行。
若是异号相加,等同于减法。
由于加减乘法是从低位开始计算的,所以我们需要一个倒序的操作(也可以不导致,但是容易混淆)
思路是
- 将把整数倒序存储,整数的个位存于数组0下标位置,最高位存于数组长度-1下标位置。之所以倒序存储,更加符合我们从左到右访问数组的习惯。
- 创建结果数组,结果数组的最大长度是较大整数的位数+1,原因很明显,可能会存在进位导致长度加一。
- 遍历两个数组,从左到右按照对应下标把元素两两相加,不满10直接在当前数组位置保存(当前数组位置的值 += 计算后的值),满10减10后存在对应的位置,进一位,填充1到下一个数组位置中。
- 把Result数组的全部元素再次逆序,若有0,去掉首位,0,就是最终结果。
代码实现
public class Main {
public static String bigNumberSum(String bigNumberA, String bigNumberB) {
//1.把两个大整数用数组逆序存储
char[] charsA = new StringBuffer(bigNumberA).reverse().toString().toCharArray();
char[] charsB = new StringBuffer(bigNumberB).reverse().toString().toCharArray();
//2.构建result数组,数组长度等于较大整数位数+1
int maxLength = charsA.length > charsB.length ? charsA.length : charsB.length;
int[] result = new int[maxLength + 1];
//3.遍历数组,按位相加
for (int i = 0; i < result.length; i++) {
int temp = result[i];
if (i < charsA.length) {
temp += charsA[i] - '0';
}
if (i < charsB.length) {
temp += charsB[i] - '0';
}
//判断是否进位
if (temp >= 10) {
temp = temp - 10;
result[i + 1] = 1;
}
result[i] = temp;
}
//4.把result数组再次逆序并转成String
StringBuilder sb = new StringBuilder();
// 判断最后一位是否发生了进位
int head=result.length-1;
if (result[result.length-1] == 0 )
head=result.length-2;
for (int i = head; i >= 0; i--)
sb.append(result[i]);
return sb.toString();
}
public static void main(String[] args)
{
System.out.println(bigNumberSum("426709752318", "95481253129"));
}
}
其他三则运算请看超长整数的四则运算