我已经编写了一个函数来计算C中两个数的nPr,你能不能帮我调整它来处理大数?
我需要能够计算高达1x10 ^ 12的值 - 我尝试过很多不同的数据类型,而且非常困难!
#include<stdio.h>
#include<math.h>
int main()
{
long int n=49,k=6;
printf("%li nPr %li = %li\n\n",n,k,nPr(n,k));
return 0;
}
long nPr(long int n, long int k);
long nPr(long int n, long int k){
if (n < 0 ){
printf("\nERROR - n is less than 0\n\n");
return -1;
}
if (k > n ){
printf("\nERROR - k is greater than n\n\n");
return -1;
}
else {
long int i,result = 1,c=n+1-k;
for(i=c; i<=n; i++)
{
result = result * i;
}
return result;
}
}
由于
Ĵ
更新:这些是没有回复的排列,
我也试过
long long nPr(long long int n, long long int k);
long long nPr(long long int n, long long int k){
if (n < 0 ){
printf("\nERROR - n is less than 0\n\n");
return -1;
}
if (k > n ){
printf("\nERROR - k is greater than n\n\n");
return -1;
}
else {
long long int i,result = 1,c=n+1-k;
for(i=c; i<=n; i++)
{
result = result * i;
}
return result;
}
}
然而,它似乎没有任何区别
答案 0 :(得分:4)
您可能希望使用bignums进行计算,也许使用GMP库。如果您切换到C ++,即使对于bignums,也可以使用the C++ class interface to GMP使用熟悉的a+b
表示法。如果你保持纯C,你需要仔细使用特定的例程,例如mpz_add添加。
当然,bignum算术(一个非常复杂的主题)比本机算术慢。
C本身不支持Bignums,你需要使用一个库(或者自己实现它,这是没有意义的:bignums的好算法很难理解和实现,所以最好使用现有的库)。
PS。 long long
不会真正有用,因为它仍然是64位。一些GCC编译器和目标处理器可能支持__int128,即128位整数,但你确实需要bignums。
答案 1 :(得分:1)
分割时不需要全面评估阶乘,这样可以降低整数溢出的风险(同时提高效率):
long factorialDivision(int topFactorial, int divisorFactorial)
{
long result = 1;
int i;
for (i = topFactorial; i > divisorFactorial; i--)
result *= i;
return result;
}
long factorial(int i)
{
if (i <= 1)
return 1;
return i * factorial(i - 1);
}
long nPr(int n, int r)
{
// naive: return factorial(n) / factorial(n - r);
return factorialDivision(n, n - r);
}
long nCr(int n, int r)
{
// naive: return factorial(n) / factorial(r) * factorial(n - r);
return nPr(n, r) / factorial(r);
}