add method

This commit is contained in:
Looly
2021-03-07 11:39:03 +08:00
parent f5172ef42b
commit 87813ae898
3 changed files with 98 additions and 26 deletions

View File

@@ -3,7 +3,7 @@
------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------
# 5.6.0 (2021-03-05) # 5.6.0 (2021-03-07)
### 新特性 ### 新特性
* 【poi 】 重要不再兼容POI-3.x增加兼容POI-5.xissue#I35J6B@Gitee * 【poi 】 重要不再兼容POI-3.x增加兼容POI-5.xissue#I35J6B@Gitee
@@ -12,6 +12,7 @@
* 【crypto 】 增加PBKDF2issue#1416@Github * 【crypto 】 增加PBKDF2issue#1416@Github
* 【core 】 增加FuncKeyMapissue#1402@Github * 【core 】 增加FuncKeyMapissue#1402@Github
* 【core 】 增加StrMatcherissue#1379@Github * 【core 】 增加StrMatcherissue#1379@Github
* 【core 】 NumberUtil增加factorial针对BigInterger方法issue#1379@Github
### Bug修复 ### Bug修复
* 【socket 】 修复Client创建失败资源未释放问题。 * 【socket 】 修复Client创建失败资源未释放问题。

View File

@@ -1428,10 +1428,62 @@ public class NumberUtil {
// ------------------------------------------------------------------------------------------- others // ------------------------------------------------------------------------------------------- others
/**
* 计算阶乘
* <p>
* n! = n * (n-1) * ... * 2 * 1
* </p>
*
* @param n 阶乘起始
* @return 结果
* @since 5.6.0
*/
public static BigInteger factorial(BigInteger n) {
if(n.equals(BigInteger.ZERO)){
return BigInteger.ONE;
}
return factorial(n, BigInteger.ZERO);
}
/** /**
* 计算范围阶乘 * 计算范围阶乘
* <p> * <p>
* factorial(start, end) = start * (start - 1) * ... * (end - 1) * factorial(start, end) = start * (start - 1) * ... * (end + 1)
* </p>
*
* @param start 阶乘起始(包含)
* @param end 阶乘结束,必须小于起始(不包括)
* @return 结果
* @since 5.6.0
*/
public static BigInteger factorial(BigInteger start, BigInteger end) {
Assert.notNull(start, "Factorial start must be not null!");
Assert.notNull(end, "Factorial end must be not null!");
if(start.compareTo(BigInteger.ZERO) < 0 || end.compareTo(BigInteger.ZERO) < 0){
throw new IllegalArgumentException(StrUtil.format("Factorial start and end both must be > 0, but got start={}, end={}", start, end));
}
if (start.equals(BigInteger.ZERO)){
start = BigInteger.ONE;
}
if(end.compareTo(BigInteger.ONE) < 0){
end = BigInteger.ONE;
}
BigInteger result = start;
end = end.add(BigInteger.ONE);
while(start.compareTo(end) > 0) {
start = start.subtract(BigInteger.ONE);
result = result.multiply(start);
}
return result;
}
/**
* 计算范围阶乘
* <p>
* factorial(start, end) = start * (start - 1) * ... * (end + 1)
* </p> * </p>
* *
* @param start 阶乘起始(包含) * @param start 阶乘起始(包含)

View File

@@ -5,6 +5,7 @@ import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.RoundingMode; import java.math.RoundingMode;
import java.util.Set; import java.util.Set;
@@ -308,6 +309,24 @@ public class NumberUtilTest {
Assert.assertEquals(2432902008176640000L, NumberUtil.factorial(20, 0)); Assert.assertEquals(2432902008176640000L, NumberUtil.factorial(20, 0));
} }
@Test
public void factorialTest2(){
long factorial = NumberUtil.factorial(new BigInteger("0")).longValue();
Assert.assertEquals(1, factorial);
Assert.assertEquals(1L, NumberUtil.factorial(new BigInteger("1")).longValue());
Assert.assertEquals(1307674368000L, NumberUtil.factorial(new BigInteger("15")).longValue());
Assert.assertEquals(2432902008176640000L, NumberUtil.factorial(20));
factorial = NumberUtil.factorial(new BigInteger("5"), new BigInteger("0")).longValue();
Assert.assertEquals(120, factorial);
factorial = NumberUtil.factorial(new BigInteger("5"), BigInteger.ONE).longValue();
Assert.assertEquals(120, factorial);
Assert.assertEquals(5, NumberUtil.factorial(new BigInteger("5"), new BigInteger("4")).longValue());
Assert.assertEquals(2432902008176640000L, NumberUtil.factorial(new BigInteger("20"), BigInteger.ZERO).longValue());
}
@Test @Test
public void mulTest(){ public void mulTest(){
final BigDecimal mul = NumberUtil.mul(new BigDecimal("10"), null); final BigDecimal mul = NumberUtil.mul(new BigDecimal("10"), null);