对于大数(超过long型所能表达的范围)的四则运算,java提供了BigInteger、BigDecimal等支持,但是有时候考官就会难为你,让你自己实现一个运算,这时候可以用下面的思路:
大数相乘:
首先我们得重新审视一下小学做过无数遍的乘法运算,可以得出如下结论:假设有A和B两个大数,位数分别是a和b,则最终结果C的位数c小于等于(a+b)。
然后我们得梳理一下乘法运算时怎么进行的。比如367*25 = 9175,结果的个位数5是367的个位数7乘以25的个位数5的乘积除以10的余数,结果的倒数第二位7是367的十位数6与25的个位数5的乘积与367的个位数7与25的十位数2乘积的和除以10的余数(读起来有点拗口)。。。以此类推。我们可以总结到:乘数a的第i位与乘数b的第j位的乘积应放在结果的第i+j位(i,j从个位开始,从零计数),由于这个乘积可能大于等于10,所以最终结果是这个乘积加上低位进的数的和除以10的余数。
描述起来有点烦乱,大家通过这个图就一目了然了~
在下面的java代码中,我们用string表示乘数和乘积(实质是转换为char数组做运算),读者只需要看看代码中的注释就可以理解了~
import java.util.Scanner;
public class BigIntegerDemo {
public static void bigNumberSimpleMulti(String f, String s) {
System.out.print("乘法:\n" + f + " * " + s + " = ");
// 判断符号
char signA = f.charAt(0);
char signB = s.charAt(0);
char sign = '+'; // 计算结果的符号
if (signA == '+' || signA == '-') {
sign = signA;
f = f.substring(1);
}
if (signB == '+' || signB == '-') {
if (sign == signB) {
sign = '+';
} else {
sign = '-';
}
s = s.substring(1);
}
// 将大数翻转并转换成字符数组
char[] a = new StringBuffer(f).reverse().toString().toCharArray();
char[] b = new StringBuffer(s).reverse().toString().toCharArray();
int lenA = a.length;
int lenB = b.length;
// 计算最终的最大长度
int len = lenA + lenB;
int[] result = new int[len];
// 计算结果集合
for (int i = 0; i < a.length; i++) {
for (int j = 0; j < b.length; j++) {
result[i + j] += (a[i] - '0') * (b[j] - '0'); // 字符表中数字字符与字符'0'的距离就是所表示数字的大小
}
}
// 处理结果集合,如果大于10就向前进一位,本身除10求余
for (int i = 0; i < result.length; i++) {
if (result[i] >= 10) {
result[i + 1] += result[i] / 10;
result[i] %= 10;
}
}
// 输出结果
StringBuffer sb = new StringBuffer();
boolean flag = true;// 标志,判断开头是否继续是0
for (int i = len - 1; i >= 0; i--) {
if (result[i] == 0 && flag) {
continue;
} else {
flag = false;
}
sb.append(result[i]);
}
if (!sb.toString().equals("")) {
if (sign == '-') {
sb.insert(0, sign);
}
} else {
sb.append(0);
}
System.out.println(sb.toString());
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner scanner = new Scanner(System.in);
String a = scanner.next();
String b = scanner.next();
scanner.close();
bigNumberSimpleMulti(a, b);
}
}
仔细想想,这也不是什么算法什么创新,就是因为long型放不下一个数 ,那我就用数组来存放呗,反正数组可以无限长(内存够就可以)~再说运算规则,大家看到,代码中的运算方式就是我们小学时做乘法题时候的计算过程,只是平时大家都忽略了,而没去总结提炼而已。
大数相加,大数相减是同样的原理~大家自己写写。
希望可以对大家有帮助~