こんにちは。
エッセーのfirst draft(第一回提出)も終わったことですし、先日投稿した「とある大学のC言語テスト問題」で見つけた改善点というのを改善して仕上げる...というわけにもいかず、別の問題点に取り組みました。
4年生で今年卒業してしまう情報科学メジャーの先輩に「とある大学のC言語テスト問題」で載せたプログラムを見せたところ、「うーん。これだと正確な値が出てない」
というご意見をいただきました。
以下に前回「とある大学のC言語テスト問題」に載せたプログラムを再度載せます。
問題:次の式に従った計算をdouble型で行い、その結果を有効桁15桁で出力するCプログラムを作成せよ。
0+1/2-3/4+5/6-7/8+9/10+......-9999/10000
13行〜16行目で行われている計算が問題です。
13行、14行で分数を小数に変換してから16行目で+やーの計算を行なっています。
ですが、c言語だと、小数点が切り落とされてしまうので、小数で計算するとそこまで正確に計算できないんです。
私が、このプログラムで使ったのはdoubleです。
このdoubleは、小数点4桁ぐらいまでしか認識していないので、これを何百回も繰り返すと、かなりの誤差になってしまいます。
そこで、先輩の提案は「分数のまま計算すればいい」
はい。やってみます。
まず分数のまま計算するには、分母を揃えなければいけません。(T_T;)
グーグル先生助けてー
今回は体系数学ではなくグーグル先生に助けてもらい、ユークリッド互除法にとって最大公約数と最小公倍数の求め方を勉強しました。
ユークリッド互除法は意外と簡単でした。まぁそれもそのはず、これは文系でも中学や高校で習う範囲です。 ああ忘れていたのか...
そして、私は最大公約数と最小公倍数が何なのか忘れてしまっていたのでグーグル先生に教えてもらいました。
分数を分数のまま計算するには、分母を最小公倍数で揃えます。
最大公約数とは、両方の数字がxで割れば割り切れる+(かつ)最も大きい数
例としては、100と50なら、50,25,5,2,1で割れます。この時最も大きいのは50です。
最小公倍数とは、両方の数に何かしらの数をかけて同じ数字になる+(かつ)最も小さい数
例としては、3と4なら、3→3,6,9,12,15 4→4,8,12,16 となり、そこで共通する数なので12です。
今は数が小さいため、感覚で計算できますが、これが1382794と10384の最小公倍数とかになってしまうと分かりにくくなってしまいます。
そこで活用されるのが
ユークリッド互除法
aとbの最大公約数を求める場合、
a>b(aの方がbより大きい)として、a÷b=?あまり?
という計算をして、あまりが0になるまで今度は b÷(前の式のあまり)=?あまり?
これで最後にあまりが0になったとき、(前の式のあまり)が最大公約数になります。
ユークリッド互除法の仕組みの解説はこちら
aとbの最小公倍数を求める場合は、
最小公倍数=a×b/最大公約数 (分子/分母)
です。
もっと分かりやすいのはこちら
これをc言語で書いて見ました。
こんな感じになりました。これでやっと「とある大学のC言語テスト問題」に組み込む材料ができました。
完成はまだですね。
0コメント