例子:编写一个程序,完成1*2*3*4*…*20的结果, 那如果是要计算1*2*3*4*…*1000的结果呢?
正常计算阶乘的方法:
我这里提供的是递归的方式:
// 计算阶乘
public static long fun(long n){
if (n == 0 || n == 1){
return 1;
}else {
return n*fun(n-1);
}
}
但很明显当我的n足够大的时候,其返回值会溢出,所以不实用。下面就可以看到,我调用这个方法:
很明显1000!溢出了,所以这种方式算不了
利用数组来解决数据溢出问题:
我下面提供的这个方法可以解决溢出问题,当然这个算法嵌套的循环太多,但是我懒得优化了,利用数组来算的思路就是满十进一,数组的每一个位置都只存一个值。
这种数据溢出还有其他方法,大家可以利用数据相关的Big数据类(例如BigInteger)来解决。我这里只提供一种,让大家能看懂的。
public static void fun1(long n){
long []sum = new long[1];
sum[0] = 1;
for (int i = 1; i <= n; i++){
// 思想 满10进一
long count = 0;
for (int j = sum.length - 1; j >= 0; j--){
sum[j] = sum[j]*i + count;
count = 0;
if (j > 0) {
while (sum[j] > 10) {
count = sum[j] / 10;
sum[j] = sum[j]%10;
}
}else {
while (sum[0] > 9){
// 数组扩容
long []sum1 = new long[sum.length + 1];
System.arraycopy(sum, 0, sum1, 0, sum.length);
for (int k = sum1.length - 1; k >= 0; k--){
if (k == 0){
sum1[0] = 0;
break;
}
sum1[k] = sum1[k-1];
}
sum1[0] += sum1[1]/10;
sum1[1] = sum1[1]%10;
sum = sum1;
}
}
// 满十位进一位
}
}
System.out.println( n + "的阶乘为:");
for (Long s : sum){
System.out.print(s);
}
}
结果:这样子就算出来了。
利用BigInteger来算:
这里我用了两种不同的算法,结果都是一样的,BigInteger可以简称为大正型,主要是以字符串的方式存储,所以理论上是可以存无限大的数据的。
public static BigInteger fun2(int n){
// BigInteger bigInteger1 = new BigInteger("0");
BigInteger bigInteger2 = new BigInteger("1");
for (int i = 1; i <= n; i++){
BigInteger i1 = new BigInteger(i + "");
bigInteger2 = bigInteger2.multiply(i1);
// bigInteger1 = bigInteger1.add(bigInteger2);
}
// System.out.println("输出为:" + bigInteger2);
return bigInteger2;
}
public static BigInteger fum2(int n){
// BigInteger bigInteger2 = new BigInteger("1");
if (n == 0 || n == 1){
return BigInteger.valueOf(1);
}else {
BigInteger i1 = new BigInteger(n + "");
return i1.multiply(fum2(n-1));
}
}