在实现K2算法时,用到了阶乘,如果数据量过大,普通阶乘会导致溢出,所以需要用到大整数阶乘。
public class BigIntegerArr {
/**
* 计算进位
*
* @param bit
* 数组
* @param pos
* 用于判断是否是数组的最高位
*/
private void carry(int[] bit, int pos) {
int i, carray = 0;
for (i = 0; i <= pos; i++)// 从0到pos逐位检查是否需要进位
{
bit[i] += carray;// 累加进位
if (bit[i] <= 9) // 小于9不进位
{
carray = 0;
} else if (bit[i] > 9 && i < pos)// 大于9,但不是最高位
{
carray = bit[i] / 10;// 保存进位值
bit[i] = bit[i] % 10;// 得到该位的一位数
} else if (bit[i] > 9 && i >= pos)// 大于9,且是最高位
{
while (bit[i] > 9)// 循环向前进位
{
carray = bit[i] / 10;// 计算进位值
bit[i] = bit[i] % 10;// 当前的第一位数
i++;
bit[i] = carray;// 在下一位保存进位值
}
}
}
}
/**
* 大整数阶乘
*
* @param bigInteger
* 所计算的大整数
*/
public String bigFactorial(int bigInteger) {
int pos = 0;//
int digit;// 数据长度
int a, b;
int m = 0;// 统计输出位数
int n = 0;// 统计输出行数
double sum = 0;// 阶乘位数
for (a = 1; a <= bigInteger; a++)// 计算阶乘位数
{
sum += Math.log10(a);
}
digit = (int) sum + 1;// 数据长度
int[] fact = new int[digit];// 初始化一个数组
fact[0] = 1;// 设个位为 1
for (a = 2; a <= bigInteger; a++)// 将2^bigInteger逐个与原来的积相乘
{
for (b = digit - 1; b >= 0; b--)// 查找最高位{}
{
if (fact[b] != 0) {
pos = b;// 记录最高位
break;
}
}
for (b = 0; b <= pos; b++) {
fact[b] *= a;// 每一位与i乘
}
carry(fact, pos);
}
for (b = digit - 1; b >= 0; b--) {
if (fact[b] != 0) {
pos = b;// 记录最高位
break;
}
}
// System.out.println(bigInteger +"阶乘结果为:");
// for(a = pos ; a >= 0 ; a --)//输出计算结果
// {
// System.out.print(fact[a]);
// m++;
// if(m % 5 == 0)
// {
// System.out.print(" ");
// }
// if(40 == m )
// {
// System.out.println("");
// m = 0 ;
// n ++;
// if(10 == n )
// {
// System.out.print("\n");
// n = 0;
// }
// }
// }
// System.out.println("\n"+"阶乘共有: "+(pos+1)+" 位");
return reverseArray(fact);
}
private String reverseArray(int[] fact) {
StringBuilder sb = new StringBuilder();
for (int i = fact.length - 1; i >= 0; i--) {
sb.append(String.valueOf(fact[i]));
}
return sb.toString();
}
private Double toLogBig(String intStr) {
// String intStr = "";
String deciStr = "";
int len = intStr.indexOf(".");
if (len == 0 || len == intStr.length() - 1) {
return 0.0;
} else if (len == -1) {
deciStr = "0";
} else {
deciStr = intStr.substring(len + 1, intStr.length());
intStr = intStr.substring(1, len);
}
len = intStr.length();
while (len > 1) {
if (intStr.startsWith("0")) {
intStr = intStr.substring(1, len);
len -= 1;
} else {
break;
}
}
len = deciStr.length();
while (len > 1) {
if (deciStr.endsWith("0")) {
deciStr = deciStr.substring(0, len - 1);
len -= 1;
} else {
break;
}
}
double ret;
len = intStr.length();
if (len < 16) {
if (intStr.length() > 4 || deciStr.length() < 9) {
intStr += "." + deciStr;
ret = Double.valueOf(intStr);
if (ret == 0) {
return 0.0;
}
ret = Math.log10(ret);
} else {
len = deciStr.length();
intStr = intStr + deciStr.substring(0, len - 8);
deciStr = deciStr.substring(len - 8, len);
ret = 8 - len;
len = intStr.length();
while (len > 1) {
if (intStr.startsWith("0")) {
intStr = intStr.substring(1, intStr.length());
} else {
break;
}
}
len = intStr.length();
if (len > 9) {
len -= 8;
deciStr = intStr.substring(8, len + 8) + deciStr;
intStr = intStr.substring(0, 8);
ret += len;
}
intStr += "." + deciStr;
ret += Math.log10(Double.valueOf(intStr));
}
} else {
len = intStr.length();
deciStr = intStr.substring(9, len) + deciStr;
intStr = intStr.substring(0, 9) + "." + deciStr;
len -= 9;
ret = Math.log10(Double.valueOf(intStr)) + Double.valueOf(len);
}
return ret;
}
//public static void main(String[] args) {
//BigIntegerArr bi = new BigIntegerArr();
//bi.bigFactorial(112);
//System.out
//.println(bi
//.toLogBig("999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999"));
//
//}
}