2

ruby の Rational ライブラリを使用して、画像の幅と高さをアスペクト比に変換しています。

文字列引数の扱いが数値引数とは異なることに気付きました。

>> Rational('1.91','1')
=> (191/100)
>> Rational(1.91,1)
=> (8601875288277647/4503599627370496)

>> RUBY_VERSION
=> "2.1.5"
>> RUBY_ENGINE
=> "ruby"

参考までに、1.91:1 は、Facebook がプラットフォーム上の画像に推奨するアスペクト比です。

191 や 100 などの値は、8601875288277647 や 4503599627370496 よりもデータベースに格納するのにはるかに便利です。

Rational テスト スイートは、この正確なケースをカバーしていないようです。

4

2 に答える 2

1

免責事項:これは、そのような偉業を実装する方法に関する知識に基づいた推測にすぎません。

ケント・ダールがすでに言ったように、フロートは正確ではなく、精度が固定されています。つまり、1.91 は実際には 1.91000000000000000001 などであり、ルビーは 1.91 として表示する必要があることを「認識」しています。

一方、「1.91」は文字列であり、基本的には「1」、「.」、「9」、「1」という文字の配列です。

つまり、フロートから有理数を構築するには、次のことを行う必要があります。

  1. を取り除きます。(数学的には、分子と分母に 10^x を掛けるか、または の後ろに数字があるので、10 を掛けます。)
  2. 最大公約数 (gcd) を求める
  3. num と denom を gcd で割る

ただし、手順 1 は Float と String では少し異なります。

  • Float には、10^x を掛ける必要があります。ここで、x は (精度のために) 2 (1.91 で考えられるように) ではなく、16 のようなものです (覚えておいてください: 1.9100...1)。
  • 文字列については、それを float にキャストして同じトリックを行うことができますが、もっと簡単な方法があります。ドットの後ろの文字数 (2) を数え、ドットを削除し、denom を掛けるだけです。 10^2... これは簡単なだけでなく、より正確な方法でもあります。

ステップ 3 を適用すると、大きな数が再び消える可能性があります。そのため、float からの有理数を処理するときに常に奇妙な結果が得られるわけではありません。

TLDR: 数値は、引数が String または FLoat であることに基づいて、異なる方法で作成されます。Floats は、精度が高いため、長い数値を生成できます。

于 2015-05-28T21:26:52.297 に答える