質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

3回答

1988閲覧

100の階乗が0となる

nanyakanya

総合スコア44

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

1クリップ

投稿2020/07/30 11:26

聞きたいこと

100の階乗を計算したいのだが、途中から値が負となり、80ごろから0になります。
どうすれば正しい値を計算できますか?
コード

c

1#include <stdio.h> 2#include <math.h> 3#define N 100 4 5int main(void){ 6 long int num = 1,i; 7 for(i = 1; i <= 100 ; i++ ){ 8 num = num * i; 9 printf("%ld\n",num); 10 } 11 //printf("%d", num); 12 return 0; 13 14}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Zuishin

2020/07/30 11:31

答えは 93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000 です。long int では足りません。
guest

回答3

0

doubleとかではなく、多倍長計算でなければ正確に計算できません。

GMP(GNU Multi-Precision Library)を使った例

C

1#include <gmp.h> 2#include <stdio.h> 3 4int main(void) 5{ 6 // 入力&チェック 7 long long n; 8 scanf("%lld", &n); 9 if (n < 0) { 10 printf("n must be positive or 0.\n"); 11 return 0; 12 } 13 14 // n!を計算 15 mpz_t x; 16 mpz_init(x); 17 mpz_set_ui(x, 1); 18 for (long long i = 2; i <= n; i++) { 19 mpz_mul_ui(x, x, i); 20 } 21 22 // 結果 23 gmp_printf("%Zd\n", x); 24 25 // 解放 26 mpz_clear(x); 27 return 0; 28} 29

実行結果

text

1(入力)100 2(出力)93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000

投稿2020/07/30 21:17

Penpen7

総合スコア698

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

環境が不明ですが、オーバーフローです。
long で表現できる範囲を越えています。

それ以上は、多倍長計算とか、別の方法を検討してください。

投稿2020/07/30 11:34

pepperleaf

総合スコア6385

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nanyakanya

2020/07/30 11:36

回答ありがとうございます! 解決しました。
guest

0

ベストアンサー

あなたが使っているC言語の処理系のlong intが扱える整数の範囲を調べましょう。32ビット符号付き整数だとすると、12の階乗までしか保持できません。

long long intが64ビット符号付き整数なら20の階乗までは保持できますが、いずれにしろ100の階乗は無理ですね。

追加分:
いや、doubleにしても有効桁数の制限があるので、正確な値は出ませんよ。

(多倍長整数を扱える)Pythonでやってみると、どのくらいの桁数かわかります。

Python

1n = 1 2for i in range(1, 101): 3 n *= i 4 print(n)

result

11 22 36 424 5120 6(中略) 7933262154439441526816992388562667004907159682643816214685929638952175999932299156089414639761565182862536979208272237582511852109168640000000000000000000000 893326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000

投稿2020/07/30 11:32

編集2020/07/30 11:41
Daregada

総合スコア11990

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nanyakanya

2020/07/30 11:33

範囲を考えていませんでした。 double型でフォーマットを%eにしたところうまくいきました。 ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問