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

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

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

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

キャスト

キャストとは、オブジェクトの型の変換が許可された場合に、明白に別の型への変換を行うプロセスのことです。

Q&A

解決済

2回答

3140閲覧

Long型に変更しても小数点以下を扱う方法

linkinpark

総合スコア42

C

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

キャスト

キャストとは、オブジェクトの型の変換が許可された場合に、明白に別の型への変換を行うプロセスのことです。

0グッド

0クリップ

投稿2021/07/31 09:54

編集2021/07/31 10:30

C

1コード 2#include <stdio.h> 3#include <stdlib.h> 4#include <string.h> 5 6double combination(int n,int k){ 7 int i; 8 double c=1; 9 for(i=1;i<=k;i++){ 10 c=(double)(n-k+i)/(double)(k-i+1)*c; 11 } 12 return c; 13} 14 15int main(void){ 16 int n,k; 17 printf("plase input n "); 18 scanf("%d",&n); 19 printf("please input k "); 20 scanf("%d",&k); 21 printf("combination(%d,%d)=%lf\n",n,k,combination(n,k)); 22 return 0; 23}

combinationとcをダブル型にすれば出力できたのですがcombinationとCの型名をlongに変更して、c=の行だけを修正することによって出力
できるようにしたいです。
((double)(n-k+i))/((double)(k-i+1))*(double)c;のようにキャスト変更したりしたのですが
うまく値が出力されませんでした。どなたかわかる方がいらしたら教えて頂きたいです。
よろしくお願いします。

追記部分
c=?????この??の部分だけいじるだけで実現して頂きたいです。

C

1コード 2#include <stdio.h> 3#include <stdlib.h> 4#include <string.h> 5 6long combination(int n,int k){ 7 int i; 8 long c=1; 9 for(i=1;i<=k;i++){ 10 c=((double)(n-k+i))/((double)(k-i+1))*(double)c; 11 } 12 return c; 13} 14 15int main(void){ 16 int n,k; 17 printf("plase input n "); 18 scanf("%d",&n); 19 printf("please input k "); 20 scanf("%d",&k); 21 printf("combination(%d,%d)=%ld\n",n,k,combination(n,k)); 22 return 0; 23}

実行結果
plase input n 13
please input k 5
combination(13,5)=546

参考までに上のコードの結果
plase input n 13
please input k 5
combination(13,5)=1287.000000

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

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

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

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

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

pepperleaf

2021/07/31 10:08

上手くできない場合とはどういう場合(コード)でしょうか。 どういう入力で、どういう結果(出力)になるのでしょうか? なお、long は、intより桁数が多い(同じ事もある)だけで、小数点は扱えません。
linkinpark

2021/07/31 10:23

変更いたしましたので確認よろしくお願いいたします。
thkana

2021/07/31 10:24

何故longにしたいのですか?
linkinpark

2021/07/31 10:29

そのような問題だったので
退会済みユーザー

退会済みユーザー

2021/07/31 10:33

https://teratail.com/help/avoid-asking > コードをください・デバッグしてください等の丸投げの質問 > 何かを作りたいのでコードを書いてほしい、学校の課題を解いてほしい等の質問は、具体的にプログラミングで困っている質問ではないと考え、推奨していません。
kazuma-s

2021/07/31 12:06

四角い枠の中に「コード」と書かないでください。
linkinpark

2021/07/31 15:39

色んなアドバイスありがとうございます。 学校の課題ではなく、コーディングしている中でわからなかったので 質問させて頂きました。
退会済みユーザー

退会済みユーザー

2021/07/31 15:51

コードをくださいって言ってるのと変わらんが。
guest

回答2

0

ベストアンサー

割り切れれば、小数点以下なんかありません。

text

1 1 * 9 / 1 = 9 2 9 * 10 / 2 = 45 3 45 * 11 / 3 = 165 4 165 * 12 / 4 = 495 5 495 * 13 / 5 = 1287

あるいは

text

1 1 * 13 / 1 = 13 2 13 * 12 / 2 = 78 3 78 * 11 / 3 = 286 4 286 * 10 / 4 = 715 5 715 * 9 / 5 = 1287

追記
意味が分かりませんか?
連続する n個の整数の積は n で割り切れます。

質問のコードは、何を何で割っていますか?
printfデバッグして答えてください。

追記2
c = c * n-- / i; あるいは c = c * (n - k + i) / i; です。

投稿2021/07/31 11:59

編集2021/07/31 16:06
kazuma-s

総合スコア8224

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

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

linkinpark

2021/07/31 15:47

plase input n 13 please input k 5 (n-k+i)/(k-i+1)=1.800000 (n-k+i)/(k-i+1)=2.500000 (n-k+i)/(k-i+1)=3.666667 (n-k+i)/(k-i+1)=6.000000 (n-k+i)/(k-i+1)=13.000000 combination(13,5)=546
linkinpark

2021/07/31 15:49

おそらくcに丸め込むために値がおかしくなっているのだと思います。 連続する n個の整数の積は n で割り切れる。この意味は分かっています。 このことを利用してコード変更してみようと思います。
kazuma-s

2021/07/31 16:03 編集

なんで言われたことができないんでしょうか? 「何」を「何」で割ってだから、n-k+i と k-i+1 の値を見ないとだめでしょう。 なんで、割った後の値だけを見ているのでしょうか?
linkinpark

2021/07/31 16:07

コード変更したらできるようになりました! ありがとうございました!!
guest

0

最後に一回、整数に丸めるんじゃ無くて、ループを回る毎に毎回整数に丸めるので、doubleの時とは値が変わってきます。
ループ毎に割るんじゃ無くて、分子と分母をそれぞれ計算して、最後に割り算をすればいいんじゃないでしょうか。

投稿2021/07/31 10:21

otn

総合スコア85901

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

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

otn

2021/07/31 10:26

回答に書いたのは、 > Long型に変更しても小数点以下を扱う方法 じゃなくて、「小数が出ないように計算する」です。
linkinpark

2021/07/31 10:27

問題ではc=の部分が一行しか答える欄がないのでそれだと 問題の答えにならないと思います。 申し訳ないのですが一行で済むような処理を教えて頂きたいです。
otn

2021/07/31 10:31 編集

不毛な努力をせず、一行でという制約を取っ払うのが良いでしょう。
linkinpark

2021/07/31 10:31

逆に言えば一行で済むような処理はないということでいいんでしょうか? 問題が間違っている可能性もあるので
otn

2021/07/31 10:36

そうですね。
linkinpark

2021/07/31 15:31

ありがとうございます
kazuma-s

2021/07/31 15:40

一行で済むような処理はあります。
Zuishin

2021/07/31 15:55 編集

計算式だけでみるとややこしいですが、これは組み合わせを計算するものです。 たとえば 10 個から 3 個を選ぶ組み合わせの数は (10 * 9 * 8) / (3 * 2 * 1) = 120 通りになります。 これを (8 / 3) * (9 / 2) * (10 / 1) という順番で行っているのが最初のコードです。 この順番を変えて 10 / 1 * 9 / 2 * 8 / 3 とすると、小数点以下が必要になりません。 なぜそうなるのかと言うと、2 で割る時には必ず二つの数がかけられているため、どちらかが偶数であるので割り切れます。 3 で割る時には必ず三つの数がかけられているため、どれかが 3 で割り切れます。 それ以降も同様です。 これを一つの式で書けば完成します。 というのが kazuma-s さんの回答です。
linkinpark

2021/07/31 16:02

とてもわかりやすい説明ありがとうございます!! 自分でコードにしていきます!!
linkinpark

2021/07/31 16:08

コード変更すればできるようになりました。Zuishinさん とてもわかりやすい説明ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問