フロートを分数に変換する
1. 序章
このチュートリアルでは、floatを分数に変換する方法を示します。 さらに、人間が読める形式の分数を取得するために、近似解を使用するか、分母を制限する必要がある場合についても説明します。
2. フロートと分数
この問題では、フロートがあり、それを分数に変換したいと考えています。
たとえば、floatがある場合、取得したい分数はです。 で、期待します。
負のフロートも同じように扱えるので、その場合に焦点を当てます。 さらに、ケースをカバーするのは簡単なので、制限します。分数に変換して、に追加します。
3. 正確な分数
おそらく、この問題に取り組む最も簡単な方法は、分母が10の累乗である分数に変換することです。例:
これを行うには、小数部がゼロになるまで10を繰り返し乗算します。
3.1. 例
たとえば、これは私たちのアルゴリズムが処理する方法です:
小数部がゼロになると停止し、結果として出力されます。
3.2. 互いに素な分子と分母
ただし、上記の例の分子と分母は互いに素ではありません。 場合によっては、分数をできるだけ単純化したいことがあります。 これを行うには、分子と分母を最大公約数(GCD)で除算します。 たとえば、35と100のGCDは5であるため、両方を5で除算し、の分数形式として取得します。
ユークリッドアルゴリズムでGCDを見つけることができます。 GCDによる除算により、出力分数の分子と分母が互いに素になることが保証されます:
4. おおよその分数
ただし、浮動小数点数は不正確になる可能性があります。たとえば、に設定しても、float変数に格納される実際の値はまたはである可能性があります。 これにより、上記のアルゴリズムは次のような読み取り不可能な小数部を出力します。
4.1. 入力フロートを最初の数桁の有効数字に切り捨てます
ドットの後の最初の数桁のみを考慮することで、このような分数を回避できます。桁のみを考慮すると、絶対誤差が。未満の見栄えの良い分数を取得できます。 ただし、必要な精度はユースケースによって異なります。したがって、あるケースでは許容できる分数が得られますが、別のケースでは不正確になる可能性があります。
おおよその分数を取得するには、上記のアプローチを少し調整する必要があります。
このアルゴリズムはどのように処理しますか? while-loop は、。のときに停止します。 その時点で、はに等しくなります。 ユークリッドの互除法は、とのGCDとして出力されます。 両方をで割ると、最終結果として得られます。
4.2. 分母を制限する
上記のアプローチでさえ失敗することがあります。 たとえば、とを使用すると、分数が得られます。 問題は、それが人間に優しいものではないということです。 人間はを理解していないので、そのような分母を持つ分数は混乱します。
代わりに、より良い解決策はまたはです。 これを処理する1つの方法は、1、2、または3の低い値に設定することです。 しかし、それでも、やなどの「読めない」分数が得られる可能性があります。
分母を10、100、20などの人間にわかりやすい整数に制限することで、この問題に対処できます。これを行うには、最初に上記のアルゴリズムで分数(正確または近似)を取得します。 次に、分母を目的の数値に変更して後処理します。
正式には、が分数であり、分母を使用する場合は、分数を次のように変換します。
(1)
次に、分子を最も近い整数に丸め、必要な分母の分数を取得します。
4.3. 例
上記の方法のいずれかを使用したとしましょう。 分母をに変更するには、ルール( 1 )を適用します。
ご覧のとおり、より人間に優しいように見えます。
ただし、は読みやすさを正確にしました。 42.0289を42に丸めたときに、追加のエラーが発生しました。 したがって、この方法は、そのようなトレードオフが許容できる場合にのみ適切です。
5. 結論
この記事では、浮動小数点数を分数に変換する4つの方法を示しました。2つの正確な手法と2つの近似です。 どちらを選択するかは、精度と読みやすさに関する要件によって異なります。