Java:避免阶乘溢出
我应该优化下面的代码,以便它计算中心二项式系数,直到整数的最大值(n=16)Java:避免阶乘溢出,java,overflow,factorial,Java,Overflow,Factorial,我应该优化下面的代码,以便它计算中心二项式系数,直到整数的最大值(n=16) 公共静态整数阶乘(int n) { int结果=1; 对于(inti=2;i6。 如何“分解”阶乘函数,使其不必处理大的数字,如2n=2*16=32 或者有更好的方法来计算中心二项系数吗?如果需要大数的阶乘,则必须使用biginger类来计算结果: public static BigInteger factorial(int n) { BigInteger result = BigInteger.ONE;
公共静态整数阶乘(int n)
{
int结果=1;
对于(inti=2;i6。
如何“分解”阶乘函数,使其不必处理大的数字,如2n=2*16=32
或者有更好的方法来计算中心二项系数吗?如果需要大数的阶乘,则必须使用biginger
类来计算结果:
public static BigInteger factorial(int n) {
BigInteger result = BigInteger.ONE;
for (int i = 2; i <= n; ++i) {
result = result.multiply(BigInteger.valueOf(i));
}
return result;
}
publicstaticbiginger阶乘(intn){
BigInteger结果=BigInteger.ONE;
对于(int i=2;i如果需要大数的阶乘,则必须使用biginger
类来计算结果:
public static BigInteger factorial(int n) {
BigInteger result = BigInteger.ONE;
for (int i = 2; i <= n; ++i) {
result = result.multiply(BigInteger.valueOf(i));
}
return result;
}
publicstaticbiginger阶乘(intn){
BigInteger结果=BigInteger.ONE;
对于(int i=2;i,除了使用大整数可能会减少计算量之外,您还可以进行一些优化,在大多数情况下,程序中可能会出现溢出
因为您至少需要两次阶乘(n),所以请计算一次并将其存储在变量中
阶乘(2*n)中有阶乘(n)。因为你之前已经计算了阶乘(n),所以你需要做的就是计算直到阶乘(2n….n),然后乘以阶乘(n)。下面是一种方法
//Pseudocode
//find factorial of n given I know already till k
int findFactorial(n, k) {
int result = 1
for i n to 1
if(i==k)
break;
result = result * n;
return result
}
//factorial(2*n) = facorial(n, k) * factorial(k)
这将大大减少您的计算量,如果您希望您的程序不会出现溢出,您可以使用大整数。除了使用大整数外,您还可以进行一些优化,这些优化可以减少您的计算量,在大多数情况下,您的程序可能会出现溢出
因为您至少需要两次阶乘(n),所以请计算一次并将其存储在变量中
阶乘(2*n)中有阶乘(n)。因为你之前已经计算了阶乘(n),所以你需要做的就是计算直到阶乘(2n….n),然后乘以阶乘(n)。下面是一种方法
//Pseudocode
//find factorial of n given I know already till k
int findFactorial(n, k) {
int result = 1
for i n to 1
if(i==k)
break;
result = result * n;
return result
}
//factorial(2*n) = facorial(n, k) * factorial(k)
这将大大减少您的计算量,如果您希望程序不会出现溢出,您可以使用大整数。如果中心二项式系数17大于最大整数,并且您只需要计算17个数字,那么显而易见的解决方案是查找表。创建一个包含17个元素的数组对n=0到16的中心二项式系数进行迭代。我想你会发现这个解非常有效
你可以在这里找到它们的列表。如果中心二项式系数17大于整数max,你只需要计算17个数字,那么显而易见的解决方案是查找表。创建一个17元素数组,其中包含n=0到16的中心二项式系数。我想你会发现这个解决方案非常有效冷冰冰的
您可以在这里找到它们的列表。只需按gamma压缩阶乘即可。
将gamma设置为10就足够了
public static double factorial(int n, double gamma)
{
double result= 1;
double gammaInv = 1.0/gamma;
for(int i = 2; i <= n; i++) result *= pow(i,gammaInv);
return result;
}
public static int centralbinom(int n, double gamma)
{
return pow(factorial(2*n,gamma) /
(factorial(n,gamma) * factorial(n),gamma),
gamma);
}
公共静态双阶乘(int n,double gamma)
{
双结果=1;
双gammaInv=1.0/伽马;
对于(inti=2;i,只需通过gamma压缩阶乘。
将gamma设置为10就足够了
public static double factorial(int n, double gamma)
{
double result= 1;
double gammaInv = 1.0/gamma;
for(int i = 2; i <= n; i++) result *= pow(i,gammaInv);
return result;
}
public static int centralbinom(int n, double gamma)
{
return pow(factorial(2*n,gamma) /
(factorial(n,gamma) * factorial(n),gamma),
gamma);
}
公共静态双阶乘(int n,double gamma)
{
双结果=1;
双gammaInv=1.0/伽马;
对于(int i=2;i)你得到了7的溢出!?@NWard 14!精确到阶乘(2*N)你有没有想过使用BigInteger?啊,当然(我应该更仔细地阅读这个问题)。BigInteger似乎是一个很好的解决方案。我想我不应该使用任何其他数据类型。你得到了7的溢出!?@NWard 14!精确到阶乘(2*N)你有没有想过使用BigInteger?啊,当然有(我应该更仔细地阅读这个问题)。BigInteger似乎是一个很好的解决方案。我想我不应该使用任何其他数据类型。