mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-05-09 23:51:34 +08:00
阶乘优化
This commit is contained in:
parent
b06d499279
commit
cdee2f32b4
@ -43,6 +43,14 @@ public class NumberUtil {
|
|||||||
*/
|
*/
|
||||||
private static final int DEFAUT_DIV_SCALE = 10;
|
private static final int DEFAUT_DIV_SCALE = 10;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 0-20对应的阶乘,超过20的阶乘会超过Long.MAX_VALUE
|
||||||
|
*/
|
||||||
|
private static final long[] FACTORIALS = new long[]{
|
||||||
|
1L, 1L, 2L, 6L, 24L, 120L, 720L, 5040L, 40320L, 362880L, 3628800L, 39916800L, 479001600L, 6227020800L,
|
||||||
|
87178291200L, 1307674368000L, 20922789888000L, 355687428096000L, 6402373705728000L, 121645100408832000L,
|
||||||
|
2432902008176640000L};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 提供精确的加法运算
|
* 提供精确的加法运算
|
||||||
*
|
*
|
||||||
@ -1429,28 +1437,50 @@ public class NumberUtil {
|
|||||||
* @return 结果
|
* @return 结果
|
||||||
* @since 4.1.0
|
* @since 4.1.0
|
||||||
*/
|
*/
|
||||||
public static long factorial(long start, long end) {
|
public static long factorial(long start, long end) {
|
||||||
if (0L == start || start == end) {
|
// 负数没有阶乘
|
||||||
return 1L;
|
if(start < 0 || end < 0) {
|
||||||
}
|
throw new IllegalArgumentException(String.format("Factorial start and end both must be >= 0, " +
|
||||||
if (start < end) {
|
"but got start=%d, end=%d", start, end));
|
||||||
return 0L;
|
}
|
||||||
}
|
if (0L == start || start == end) {
|
||||||
return start * factorial(start - 1, end);
|
return 1L;
|
||||||
}
|
}
|
||||||
|
if (start < end) {
|
||||||
|
return 0L;
|
||||||
|
}
|
||||||
|
return factorialMultiplyAndCheck(start, factorial(start - 1, end));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 计算阶乘
|
* 计算范围阶乘中校验中间的计算是否存在溢出,factorial提前做了负数和0的校验,因此这里没有校验数字的正负
|
||||||
* <p>
|
* @param a 乘数
|
||||||
* n! = n * (n-1) * ... * 2 * 1
|
* @param b 被乘数
|
||||||
* </p>
|
* @return 如果 a * b的结果没有溢出直接返回,否则抛出异常
|
||||||
*
|
*/
|
||||||
* @param n 阶乘起始
|
private static long factorialMultiplyAndCheck(long a, long b) {
|
||||||
* @return 结果
|
if (a <= Long.MAX_VALUE / b) {
|
||||||
*/
|
return a * b;
|
||||||
public static long factorial(long n) {
|
}
|
||||||
return factorial(n, 1);
|
throw new IllegalArgumentException(String.format("Overflow in multiplication: {%d} * {%d}", a, b));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 计算阶乘
|
||||||
|
* <p>
|
||||||
|
* n! = n * (n-1) * ... * 2 * 1
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param n 阶乘起始
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public static long factorial(long n) {
|
||||||
|
if (n < 0 || n > 20) {
|
||||||
|
throw new IllegalArgumentException(String.format("Factorial must have n >= 0 and n <= 20 for n!, " +
|
||||||
|
"but got n = %d", n));
|
||||||
|
}
|
||||||
|
return FACTORIALS[(int) n];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 平方根算法<br>
|
* 平方根算法<br>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user