なんちゃってプログラマーの勉強部屋

自分が学んだ諸々を備忘録的に公開します。

小数を分数になおす

さて、前回の記事にて、
programandmath.hatenablog.com

ってのを書きましたが。今回は、小数を分数になおす方法。
ちなみに、$\cfrac{f}{i} \cdot i = f$ が成り立つことがわかると思うが、このことから、ある小数($\cfrac{f}{i}$)に、任意の $i$ を掛ければ、整数 $f$ になるということを利用する。
したがって、小数 $\cfrac{f}{i} (= n)$ を $i$ 倍したものをある整数 $f_1$ とし、これに 1 を加えたものを $f_2$ とする。
ちなみに、そんな $i$ をどう決めるのか? これは、for ループを使えばよい。つまり、ある範囲の中から、ループを回していって、うまく $f$ が整数になるものを探すわけだ。
ところで、これで本当にその $i$ が求めれば、該当する分数になるかというと、そうならないかもしれない。そこで、この $i$ で、$f_1$ と $f_2$ を実際に $i$ で割ってみれば良い。そして、その値のどちらかが、入力値 $\cfrac{f}{i} (= n)$ と、ある程度の(無視してもよいような)誤差範囲内にあれば、結果として、それは求める分数とみなしてもよいということになる。
以下、実際のコード。いろいろと参考にしたページがあったのを、自分で C言語で組み直した感じ。

void dec2frac(double n, long max, int diff, long frac[])
{
         long i, j1, j2;
         double v1, v2;
         for(i = 1; i <= max; i++)
         {
                 j1 = (long)(n * i); j2 = j1 + 1;
                 v1 = (double)j1 / (double)i;
                 v2 = (double)j2 / (double)i;

                 if(fabs(v1 - n) < pow(10, -(diff)))
                 {
                         frac[0] = j1; frac[1] = i;
                         return;
                 }
                 else if(fabs(v2 - n) < pow(10, -(diff)))
                 {
                         frac[0] = j2; frac[1] = i;
                         return;

                 }
         }
         frac[0] = 0; frac[1] = 0;
         return;
 }