» 詳しい使用方法や、エラーで展開できない際の対応方法などはこちら
小数(浮動小数点数)から分数へ近似的に変換するツール
>> Webページ上でそのまま使えるJavaScript版はこちら
このプログラムは、小数を、適当な誤差の範囲内で、近い分数に変換するツールプログラムです。 なお、ここでの小数とは、関数電卓や計算機などでよく使われる形式の、いわゆる浮動小数点数を指します。
スポンサーリンク
使用方法
ダウンロードと展開(解凍)
まず、PC(スマホは未対応)で上の画面の「 ダウンロード 」ボタンを押してください。 するとZIP形式で圧縮されたファイルがダウンロードされます。
その後、ZIPファイルを右クリックして「すべて展開」や「ここに展開」などで展開(解凍)してください。 展開が成功すると、ZIPファイルと同じ名前のフォルダができ、その中にZIPファイルの中身が入っています。
» 展開がエラーで止まってしまう場合や、ファイル名が文字化けしてしまう場合は…
プログラムの起動
Windows をご使用の場合
上記でZIPファイルを展開したフォルダ内にある、以下のバッチファイルをダブルクリック実行してください:
もしプログラムを書き変えながら使いたい場合は、代わりに「 VCSSL_Editor__プログラム編集はこちら.bat 」を実行してください。
正常に起動できると、初回のみ、Java実行環境を入手するか等を尋ねられるので、適時答えて済ませると、プログラムが起動します。 2回目以降はすぐに起動します。
Linux 等をご使用の場合
ZIPファイルを展開したフォルダ内へコマンドライン端末で cd して、以下の通り入力して実行してください:
(プログラムの内容を書き変えながら使いたい場合は、代わりに VCSSL_Editor.jar を実行)
» javaコマンドが使用できない等のエラーが表示される場合は…
起動後の操作方法
起動すると、まず変換したい値を尋ねられます。ここで分数に変換したい小数の値を入力してください。 Ctrlキー と V キーの同時押しで、貼り付けができます。 たとえば、21.333333333333 などを入力してみてください( 64/3 の値です )。
続いて、分母の上限を尋ねられます。 変換結果は、ここで指定した範囲から、変換対象の小数値に近い分数の値を片っ端から求めて、 比較する事によって探されます。 普通は 10000 程度でいいと思います。あまり広い範囲から探して、例えば 1.23456789 に対して 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/Vnanoコード( 拡張子が「.vcssl」や「.vnano」のファイル )は実質的な著作権フリー(パブリックドメイン) である CC0 の状態で公開しています※。 記事中にC言語/C++/Java言語などでのサンプルコードが掲載されいてる場合は、それらについても同様です。 そのままでのご利用はもちろん、改造や流用などもご自由に行ってください。
※ ただし、このコードの配布フォルダ内には、ダウンロード後すぐに実行できるように、 VCSSLの実行環境も同梱されており、そのライセンス文書は「 License 」フォルダ内に同梱されています (要約すると、商用・非商用問わず自由に使用できますが、使用の結果に対して開発元は一切の責任を負いません、といった具合の内容です)。 配布フォルダ内の各構成物の一覧やライセンスについては「 ReadMe_使用方法_必ずお読みください.txt 」をご参照ください。
※ Vnano の実行環境については、別途スクリプトエンジンのソースコードも一般公開しており、 何らかのソフトウェア内に組み込んでご利用いただく事も可能です。詳細はこちらをご参照ください。
この記事中の商標などについて
- OracleとJavaは、Oracle Corporation 及びその子会社、関連会社の米国及びその他の国における登録商標です。文中の社名、商品名等は各社の商標または登録商標である場合があります。
- Windows は、米国 Microsoft Corporation の米国およびその他の国における登録商標です。この記事は独立著作物であり、Microsoft Corporation と関連のある、もしくはスポンサーを受けるものではありません。
- Linux は、Linus Torvalds 氏の米国およびその他の国における商標または登録商標です。
- その他、文中に使用されている商標は、その商標を保持する各社の各国における商標または登録商標です。
角度の「度」とラジアンとを相互変換し、図示もするツール |
|
|
45度などの「度」の値と、ラジアンの値とを相互に変換できるツールです。対応する角度の図示もできます。 |
FizzBuzz の答えを表示するプログラム |
|
|
プログラミングの練習問題としても有名な、FizzBuzz 問題の答えを表示するプログラムの例です。 |
Vnano版 | 積分値のグラフ描画用データを出力するプログラム |
|
|
数値的に積分を行い、結果の関数をグラフに描くためのデータを出力するコードです。 |
Vnano版 | 積分値を求めるプログラム (数値積分) |
|
|
矩形法/台形法/シンプソン法を用いて、積分の値を数値的に求めるコードです。 |
入力された数式を積分して値とグラフを表示するツール |
|
|
画面上で数式を入力すると、それを数値的に積分し、値とグラフを表示してくれるGUIツールです。 |
シンプソン法による数値積分 |
|
|
積分の値を数値的に求めます。台形法よりも高精度な方法として、被積分関数を微小区間内で二次関数近似して求めた面積を足しあげる、シンプソン法を使用します。 |
台形法(台形近似)による数値積分 |
|
|
積分の値を数値的に求めます。長方形近似よりも高精度な方法として、台形で近似した微小領域を足しあげる方法を使用します。 |
矩形法(長方形近似)による数値積分 |
|
|
積分の値を数値的に求めます。長方形の短冊(矩形)で近似した微小領域を足しあげる、最も単純な方法を使用します。 |
小数(浮動小数点数)から分数へ近似的に変換するツール |
|
|
小数(浮動小数点数)を、適当な誤差の範囲内で、近い分数に変換してくれるツールプログラムです。 |
円周率1万桁の計算(ガウス=ルジャンドル法) |
|
|
ガウス=ルジャンドル法により、円周率を1万桁まで計算するプログラムです。 |
試し割り法による素数判定ツール |
|
|
試し割り法を用いて、素数判定を行ってくれる簡易ツールです。 |