2016-11-25 19 views
2

小数点以下の桁を指定すると、おおよその等価性を照会する良い方法がありますか?クエリの近似等価

あなたは範囲を使用することができます:

Purchase.where(total: (value - delta)..(value + delta)).first 

をしかし、それはRailsは通常、浮動小数点数を常に正確に表現できないことを考えると、あなたのための解決しようとする一般的な十分な問題のように見えます。

+0

(http://stackoverflow.com/questions/40807770 /奇妙な丸め問題)。 – ndn

答えて

1

アクティブレコードでこれをきちんと行うことができる宝石があるのか​​どうかわかりませんが、範囲を使用する代わりにSQL丸めを試しましたか?次のようなものがあります。

Purchase.where('ROUND(total, 2) = ?', 30.67) 

このanswerを参照してください。その中のリンクもdocsです。最後に、this answerのようなセントセントをデータベースに格納し、表示用に変更するだけで、浮動小数点の扱いを避けることができます。

+0

おっと!キャッチ@ndnありがとう! – mlabarca

+0

フロート値は悪く、常に片頭痛につながります。それを整数に変換するか、データベースのネイティブdecimal型を使用します。 – mysmallidea

+0

@mysmallidea、私はデータベースのネイティブdecimal型*を使用しています。 – ndn

1

私はあなたの質問でそれをやっている方法が最良の方法だと思います。ご存じのように、Rubyは浮動小数点値を扱う際に悪い(悪いと思います)(9.95 * 100を試してください)。データベースの値を浮動小数点値ではなく小数値として格納している限り、大丈夫です。

私が改善すると考えることができる唯一の事は、クラスメソッドにのようなものを、それを抽出することである:浮動問題は、[それほど明白ではない]ことになっ

# models/purchase.rb 
def self.find_approximate(value, delta=0.1) 
    where(total: (value - delta)..(value + delta)) 
end 

Purchase.find_approximate(9.95).first 
+1

Rubyが特に悪いとは言いません。浮動小数点数をネイティブ実装にマップするすべての言語は、994.999を提供します... – ndn