Ruby
 Computer >> コンピューター >  >> プログラミング >> Ruby

Rubyでの分数と有理数の操作

告白します。浮動小数点数はちょっと嫌いです。確かに、コンピュータの場合は便利ですが、人間の場合は、次のような状況で頭をかいてしまいます。

129.95 * 100
# => 12994.999999999998

これは数学的調和に直面して飛ぶだけでなく、悪いUXでもあります。

レシピで0.37211927843カップの小麦粉を測定するように指示された場合、著者が何であるかについて自分自身を笑わせ、カップの3分の1を測定し始めたでしょう。

ほとんどの人は、任意の10進数について考えるよりも、分数についてはるかに簡単に考えることができます。そのため、アプリが数値を人に伝えようとしている場合は、数値を分数で表現する方法を検討するのが理にかなっているかもしれません。

RubyのRational クラスは、有理数を操作するための優れたツールです。有理数を計算する機能を提供するだけでなく、危険な浮動小数点数を近似する単純な分数を見つけることもできます。見てみましょう!

有理数とは何ですか?

私たちの目的では、「有理数」は「分数」を言うための空想的な方法にすぎません。分子と分母の2つの部分があります。

1/2 # Numerator is 1. Denominator is 2. 
5   # Numerator is 5. Denominator is 1.

Rubyでは、有理数は整数や浮動小数点数と同じように独自のデータ型を取得します。新しい有理数を作成するには、いくつかの方法があります。

3/2r              # This syntax was introduced in Ruby 2.1
1.5.to_r          # Floats can be converted to rationals via `to_r`
"3/2".to_r        # ...so can strings
Rational('3/2')   # This is how we had to do things in the olden days
Rational(3, 2)    # ...see how hard life was?
簡単な数学

2つの有理数を加算、減算、乗算、または除算すると、結果も有理数になります。

2/3r + 1/3r
# => (1/1)
2/3r - 1/3r
# => (1/3)
2/3r * 1/3r
# => (2/9)
(2/3r) / (1/3r) # We need parens here to avoid confusing the interpreter
# => (2/1)

他のすべての数学演算子も、期待どおりに動作します: ** >< 、など。

一般的な規則は、結果が分数になるためには、両方の入力が分数でなければならないということです。私が見つけた唯一の例外は整数です。すべての整数が有理数であるため、Rubyは賢明なことを行い、すべての人に有理数の出力を想定します。

2/3r + 2
# => (8/3)
概算

有理数の最も有用な点の1つは、頭の中で近似して簡単に計算できることです。これを利用するには、分数を単純に保つ必要があります。 3/2 3320774221237909/2251799813685248の代わりに 。

幸い、Rubyを使用すると、これらの正確だが醜い数値を概算でありながらきれいな数値に変換する簡単な方法が提供されます。私は合理化について話している メソッド。

外観は次のとおりです。

# Precise but ugly
(1.47472).to_r
=> (3320774221237909/2251799813685248)

# Less precise, but pretty
(1.47472).to_r.rationalize(0.05)
=> (3/2)

合理化メソッドには1つの引数があります。これは、許容範囲、つまり単純さと引き換えに喜んで受け入れる精度の量を指定します。

このメソッドは、許容範囲内で最小公分母を持つ数値を見つけます。これが私の意味です:

# What's the number with the lowest denominator between 5/10 and 7/10?
(6/10r).rationalize(1/10r)
# => (1/2)

# What's the number with the lowest denominator between 11/20 and 13/20?
(6/10r).rationalize(1/20r)
=> (3/5)

# ..and between 1/10 and 11/10?
(6/10r).rationalize(1/2r)
=> (1/1)
クルーダー近似

分数に対応する整数または浮動小数点数を見つけるだけでよい場合は、いくつかのオプションがあります。

# Return the nearest integer. 
(6/10r).round
# => 1

# Round down
(12/10r).to_i 
# => 1
有理数の制限

有理数とRubyを使用する場合は、注意すべきいくつかの制限があります。もちろん、ゼロで割ることはできません:

4/0r
ZeroDivisionError: divided by 0

また、無理数を有理数として処理しようとすると、奇妙な動作に遭遇します。

# Umm, isn't the square root of 2 irrational?
Rational(Math.sqrt(2))
# => (6369051672525773/4503599627370496)

# And I'm pretty sure PI is irrational as well.
Rational(Math::PI)
# => (884279719003555/281474976710656)

Rubyに無理数を処理するように依頼するのは合理的であると予想されるかもしれませんが、ある種の例外が発生します。しかし残念ながら、Rubyはこれを行うのに十分賢くないようです。代わりに、これらの無理数の浮動小数点近似を有理数に変換します。大きな問題ではありませんが、注意が必要です。


  1. Rubyでのマージソートの調査

    これは、Rubyを使用したさまざまなソートアルゴリズムの実装を検討するシリーズのパート3です。パート1ではバブルソートについて説明し、パート2では選択ソートについて説明しました。 このシリーズの以前の投稿で説明したように、データの並べ替え方法を理解することは、ソフトウェアエンジニアのツールキットの不可欠な部分です。幸い、Rubyのようなほとんどの高級言語には、配列のソートに効率的な組み込みメソッドがすでに組み込まれています。たとえば、.sortを呼び出す場合 アレイでは、内部でクイックソートを使用しています。この投稿では、クイックソートと同様のアルゴリズム(マージソート)を学習します。これ

  2. コマンド プロンプトの基本:ファイルとフォルダの操作

    コマンド プロンプトの基本:ファイルとフォルダーの操作 エクスプローラーを使用してファイルをナビゲートするのにうんざりしていませんか?開発者または IT プロフェッショナルでない限り、それはあなたではないかもしれません。開発者であろうとなかろうと、基本的なコマンド ラインの知識があると常に役に立ちます。 このガイドでは、ターミナルで作業するときに使用できる一般的なファイル操作コマンドをいくつか紹介します。 コマンド プロンプト (または PowerShell または Windows ターミナル) からファイル システムを走査するには、次の 2 つの基本的なコマンドが必要です:cd と d