Now Loading...
※ ZIPファイルを展開して「 VCSSL.jar 」をダブルクリックして下さい。 動作には Java が必要です。 このVCSSLコードのライセンスは パブリックドメイン(CC0)です(詳細: ReadMe.txt)。

小数(浮動小数点数)から分数へ近似的に変換する

小数(浮動小数点数)を、適当な誤差の範囲内で、近い分数に変換するプログラムです。

>> JavaScript版はこちら

概要

このプログラムは、小数を、適当な誤差の範囲内で、近い分数に変換するプログラムです。 なお、ここでの小数とは、関数電卓や計算機などでよく使われる形式の、いわゆる浮動小数点数を指します。

使用方法

ダウンロードと起動

上の画面の「 ダウンロードして実行 」ボタンを押して ZIP ファイルをダウンロードし、 右クリックして「すべて展開」してください。 展開した中にある「 VCSSL.jar(JARファイル) 」をダブルクリックすると、プログラムが起動します。

起動後の操作方法

起動すると、まず変換したい値を尋ねられます。ここで分数に変換したい小数の値を入力してください。 Ctrlキー と V キーの同時押しで、貼り付けができます。 たとえば、21.333333333333 などを入力してみてください( 64/3 の値です )。

小数入力画面

続いて、分母の上限を尋ねられます。 変換結果は、ここで指定した範囲から、変換対象の小数値に近い分数の値を片っ端から求めて、 比較する事によって探されます。 普通は 10000 程度でいいと思います。あまり広い範囲から探して、123456789/1000000000 のような強引な結果が得られても微妙なので…

探索範囲入力画面

最後に、入力された小数と、結果の分数との間に、許容できる誤差の範囲を尋ねられます。 指定した誤差の範囲内に収まる分数が、変換結果として表示されます。

誤差範囲画面

入力が終わると、分数の探索が始まり、結果が表示されます。 この場合の例では 64 / 3 が得られます。

結果出力画面

なお同時に、その分数を浮動小数点数で実際に近似した値も表示されます(上図参照)。 あくまで近似的な浮動小数点数であるため、末尾に丸め誤差や桁落ち誤差を含む場合がありますが、 妥当性判断の参考にしてください。

背景や処理内容など

小数を分数に直したい…

例えば、表計算ソフトのセルとか、数値計算のパラメータとかに、 パッと見た感じではでたらめな小数が突然書いてあって、 「この値は確か、何かの整数同士で割り算した(分数の)値だったと思うけれど、 メモっていなかったので忘れてしまった… もとの分数が何だったか知りたい ! 」 という場合、手計算でもとの分数を求めるのは結構面倒です。

筆者が個人的に、つい最近まさにそういった必要に迫られたため、自動でいい感じの分数を探してくれるよう、 即席で書いたのがこのプログラムです。

処理内容

即席なので処理内容も結構単純で、 「与えられた小数に近そうな分数を片っ端から探し、 その値を求めて、誤差が一定範囲内であれば正解と見なして表示する」 という感じの処理になっています。

本当はもうちょっと数学的にうまいことやれるのでは、と思いますが、 とりあえず筆者は個人的にはもう目的を達成できたので、 そのまま公開します。 もしいつか、莫大な大きさの分母・分子を持つ分数でも探す必要が生じた場合などは、また手を入れるかもしません。

「近くなりそうな分数」の範囲

上で「近くなりそうな分数を探す」と言いましたが、 人間だと勘で適当にそれっぽいのを試すという事ができても、コンピュータに勘はないので、 この点に少し補足を加えておきます。

一番単純な探し方として、例えば「分母と分子それぞれ 1 から 100万 まで、 全ての組み合わせから探す」みたいなものが思い浮かびますが、 それだと総数は100万の2乗で1兆通りなったりして、探す範囲がやや大変な事になり、 入力から出力までのレスポンスが遅れて地味に鬱陶しいです。 その1兆個の分数の中には、比べるまでもなく大きすぎたり、小さすぎたりするやつが大半で、 目的の小数に近いやつはごくごく一部です。

さすがそれだと効率が悪すぎるので、少し探す範囲を絞り込みます。 分数に直したい小数の値を f としましょう。 そして、ある分母の整数 i が与えられたとして、分子を探す範囲を絞り込みます。 まず、当たり前の事ですが「 f*i / i = f 」となりますね。 という事は、f*i に近い整数を分子にすれば、分数の値は f に近いはずです。

f*i の端数を切り捨てて整数にしたものを j1 としましょう。これは f*i 以下の値であるため、 分数 j1 / i は f 以下の値となります。

また、整数化で切り捨てた端数は1以下なので、j1 + 1 を新たに j2 とすると、 これは f*i より大きい値となり、従って分数 j2 / i は f より大きい値となります。j1の逆ですね。

j1 と j2 は隣接する整数なので、挟み撃ち的な感じで、結局はこの2つを分子として採用すれば、 どちらかが最も近い分数値を与えてくれます。 つまり、ある分母 i の値について、分子は f*i と f*i+1 の2通りだけ採用すれば、 近似値を探す範囲としては十分なわけです。 あとは、分母 i をひたすら増やしていって、 誤差が規定範囲内に収まる分数を探せば OK です。

コード解説

実際のプログラムのコード内容について簡単に説明します。 このプログラムのコードはVCSSLで記述されています。 今回の内容は単純なので、大体C言語っぽい感覚で読める感じになっていると思います。

なお、JavaScript版のコードもVCSSL版とほとんど同じなので、ここではとりあえずVCSSL版のコードで解説します。 JavaScript版のコードはJavaScript版のページに掲載しています。

コード全体

まずは、コード全体を見てみましょう。30行程度の短いコードです。

以上です。流れとしては、先頭あたりでユーザーから近似対象の小数値やパラメータを入力してもらい、 真ん中あたりでループを回して近い分数を探し、見つかれば出力してそのままプログラムを終了する感じです。 良い分数が見つからなければ、ループを抜けて末尾まで下りてきて「見つかりませんでした」と言って終了、 といった具合です。

以下では、各部についてもう少し見てみます。

先頭部分

まず先頭部分です。

先頭の「 coding Shift_JIS; 」では、プログラムの文字コードを明示しています( UTF-8も可 )。 必須ではありませんが、書いておくと文字化けするのを防げます。

「 import Math; 」の部分は、数学関数を扱うためのライブラリ「 Math 」を読み込んでいます。 誤差の絶対値を求める際に abs 関数を使うので必要です。

ユーザー入力

続いて、ユーザーに近似対象の小数値やパラメータを入力してもらう部分です。

input関数は、ダイアログを表示して、ユーザーに値を入力してもらうための関数です。 input関数の戻り値は string ですが、float や int で受け取っているので、代入時に暗黙的に変換されます。

近い分数を探す

続いて中核部分です。分母 i を増やしながら、近似対象の小数 f に近い分数を探します。

処理内容の解説でも述べた通り、それぞれの分母 i について、分子は f*i と f*i+1 の2通りから探せば十分です。

誤差が規定範囲内に収まるものが見つかった場合は、出力してそのまま exit でプログラムの実行を終了します。

見つからなかった場合の処理

見つからなかった場合は、上のループを抜けて、見つからなかった旨を告げて実行終了します。

コードのライセンス

このVCSSLコードは著作権フリー(パブリックドメイン)で公開しています。JavaScript版のコードも同様です。 そのままでのご利用はもちろん、言語の種類を問わず、改造や流用などもご自由に行ってください。



スポンサーリンク



台形法(台形近似)による数値積分

積分の値を数値的に求めます。長方形近似よりも高精度な方法として、台形で近似した微小領域を足しあげる方法を使用します。
短冊法(長方形近似)による数値積分

積分の値を数値的に求めます。長方形の短冊で近似した微小領域を足しあげる、最も単純な方法を使用します。
小数(浮動小数点数)から分数へ近似的に変換する

小数(浮動小数点数)を、適当な誤差の範囲内で、近い分数に変換するプログラムです。
円周率1万桁の計算(ガウス=ルジャンドル法)

ガウス=ルジャンドル法により、円周率を1万桁まで計算するプログラムです。
試し割り法による素数判定

試し割り法を用いた、素数判定のプログラムです。
スポンサーリンク

インデックス
台形法(台形近似)による数値積分

積分の値を数値的に求めます。長方形近似よりも高精度な方法として、台形で近似した微小領域を足しあげる方法を使用します。
短冊法(長方形近似)による数値積分

積分の値を数値的に求めます。長方形の短冊で近似した微小領域を足しあげる、最も単純な方法を使用します。
小数(浮動小数点数)から分数へ近似的に変換する

小数(浮動小数点数)を、適当な誤差の範囲内で、近い分数に変換するプログラムです。
円周率1万桁の計算(ガウス=ルジャンドル法)

ガウス=ルジャンドル法により、円周率を1万桁まで計算するプログラムです。
試し割り法による素数判定

試し割り法を用いた、素数判定のプログラムです。

お知らせ( Twitter )

スポンサーリンク