ページ 1 / 1
組み合わせの数
Posted: 2008年11月19日(水) 21:59
by 初心者
下記のように組み合わせの数を求めるプログラムを作ったのですが
大きい数を入力すると値が求められないときがありました。
値が何より大きくなると求められないとかあるのでしょうか?
#include <stdio.h>
long fact2(int,int);
main()
{
int n, m;
long c;
printf("input n m =");
scanf("%d %d",&n, &m);
c = fact2(n,m) / fact2(m,m);
printf("%dC%d = %d\n",n, m, c);
}
long fact2(int n,int m)
{
int i;
long c=1;
for(i=n; i>=n-m+1; i--) c*=i;
return(c);
}
Re:組み合わせの数
Posted: 2008年11月19日(水) 22:09
by box
> 値が何より大きくなると求められないとかあるのでしょうか?
nとmの値の内容によります。
> for(i=n; i>=n-m+1; i--) c*=i;
nとmの値によっては、cがlong型で扱える範囲を超える(オーバーフロー)ことがあります。
計算の順序を工夫することで、オーバーフローする時期を遅らせることはできます。
それでも、nとmの値によっては、いつかはオーバーフローします。
似たような話を、最近どこかのスレッドで見かけたような記憶があります。
Re:組み合わせの数
Posted: 2008年11月19日(水) 23:18
by non
long型の最大値はLONG_MAXですから、
#include <limits.h>
#include <stdio.h>
int main(void)
{
printf("%ld\n",LONG_MAX);
return 0;
}
を実行したら、その環境のlong最大値がわかります。
Re:組み合わせの数
Posted: 2008年11月20日(木) 11:35
by non
ちょっと暇だったんで、作ってみました。
n
Cr=n-1
Cr-1
+n-1
Cr の公式を使って、再帰呼び出しにしてみました。
fact2が初心者さんの関数、factが私が作った関数です。
#include <stdio.h>
long fact(int,int);
long fact2(int,int);
int main(void)
{
int n, m;
long c;
printf("input n m =");
scanf("%d %d",&n, &m);
c = fact(n,m);
printf("fact :%dC%d = %ld\n",n, m, c);
c = fact2(n,m) / fact2(m,m);
printf("fact2:%dC%d = %ld\n",n, m, c);
return 0;
}
long fact(int n,int r)
{
if(r==1)
return n;
if(r==n-1)
return n;
return(fact(n-1,r-1)+fact(n-1,r));
}
long fact2(int n,int m)
{
int i;
long c=1;
for(i=n; i>=n-m+1; i--) c*=i;
return(c);
}