前面几讲介绍过JDK所提供的BigInteger能完成大数计算,如果不用它,直接使用数组表达大数,你能实现相同的功能吗?
要求:
(1)用你的大数类实现加和减两个功能
(2)阅读BigInteger类源码,弄清楚它是使用什么算法实现加减乘除四种运算的?
(3)通过互联网查找大数运算的相关资料,给你的大数类添加乘、除、求阶乘等其它功能。
public class Factorial
{
private static final int MAX = 1000000000;
public static final String ENTER = "\n";
public static void main(String args[])
{
int l = 10000;
int[] result = getFacorial(l);
StringBuilder sb = new StringBuilder();
sb.append(result[result.length - 1]);
for (int i = result.length - 2; i >= 0; i--)
{
int n = String.valueOf(result[i]).length();
sb.append(("000000000".substring(n) + result[i]));
}
sb.append(ENTER);
System.out.println("一共" + sb.length() + "位:");
System.out.print(sb.toString());
}
/**
* 递归算阶乘
* @param L
* @return
*/
public static int[] getFacorial(int n)
{
if (n == 1) return new int[]{1};
int[] multiplyToLen = multiplyToLen(getFacorial(n - 1), n);
return multiplyToLen;
}
/**
* 主要算法还是跟BigInteger一样,只不过我为了输出,每个int只保留9位。
* @param value
* @param n
* @return
*/
private static int[] multiplyToLen(int[] value, int n)
{
//n可能大于max,分成两个
long dh = n / MAX;
long dl = n % MAX; //后32位
int xlen = value.length;
//L相当于两个int,可以得出最后的位数最多为 xlen + 2
//可以自己去证明:n位 * m位,结果最多为 n + m位,最少为n + m - 1位
int[] result = (dh == 0L) ? (new int[xlen + 1]) : (new int[xlen + 2]);
long carry = 0;
for (int i = 0; i < xlen; i++)
{
long product = (value[i]) * dl + carry;
result[i] = (int)(product % MAX);
carry = product / MAX;
}
result[xlen] = (int)carry;
//算高位
if (dh != 0L)
{
carry = 0;
for (int i = 0; i < xlen; i++)
{
long product = (value[i]) * dh + result[i + 1] + carry;
result[i] = (int)(product % MAX);
carry = product / MAX;
}
result[result.length - 1] = (int)carry;
}
//carry = 0,证明不需要进最后一位,删除
if (carry == 0L)
result = java.util.Arrays.copyOfRange(result, 0, result.length - 1);
return result;
}
}