2011-01-20 22 views
0

Rails 3.0.3を使用してMySQLデータベースに緯度と経度を格納しています。ここで私は、テーブルを作成するために使用される移行の一部は、(与えられた精度で小数点値に注意してください)です。Ruby BigDecimalとMySQLの小数精度の不一致

create_table :dummies do |t| 
    t.decimal :something, :precision => 13, :scale => 10 
end 

次RSpecの例それは間違って起こっている説明すべきです。

いくつかの計算にはBigDecimalを使用し、その結果のmy_valueは大きな精度(マイグレーションで指定されたものより大きい)の数値です。私はデータベースにオブジェクトを格納して、再びそれを取得します。

it 'should be equals before and after save' do 
    my_value = BigDecimal('4.123456789') * 5000 # more precise than defined in the migration 
    dummy = Dummy.new(:something => my_value) 
    location.save! 
    Dummy.first.something.should == dummy.something 
end 

これは、MySQLで(小数点以下の精度が起こっている理由を私は理解して:その精度が同じではないではありませんので、それはもはや同じ数であるとして、データベースの値と元の値が失敗した比較

!= BigDecimalのように)、データベース制約を守るためにデータベースに書き込む前に、my_value BigDecimalの精度をどのように制限できるか教えてください。

ありがとうございます!

答えて

4

mySQLでは、これらの地理座標を格納するためにFLOATを使用します。高精度小数点として格納するのは意味がありません。緯度の1/60は航海ですので、1フィート(約1/3メートル)は約3ミクロ度です。 (3E-06)

IEEE単精度浮動小数点(エラー)のためのイプシロンは、あなたが179.9996度にしている場合でも、およそ6E-08

GPSとジオコーディングがその詳細はありませんです。

200倍のトポマップなどを詳細に作成する場合は、普遍的な横方向のメルカトルまたはランバートなどの高精度投影を使用する必要があることは既に知っているでしょう。地球を球として近似する限界。しかし、あなたが店舗検索型のアプリをやっているならば、そのような精度を必要とせず、欲しくなくできず、得ることもできません。

Rubyプログラムで10進数を使用する必要がある場合は、mySQLに格納する前にfloatに変換してください。

+0

おかげオリのようなものを試してみました。問題は私が後で計算のために座標を使用していることです。そのため私はBigDecimalに行って、浮動小数点数はここで奇妙な値を返す可能性があると思います。検証の前に浮動小数点数に変換して、私はあなたの最後の解決策を試みます。 – Cimm

+0

@Cimm - これらの計算ではfloatは正常に動作します。真剣に。 –

+0

もう一度ありがとう!私は 't.float:latitude、:limit => 51'に行きました。これは、RailsでFloatを使用し、その値をMySQLにDoubleとして格納します。 – Cimm

0

私は

new_value = number_with_precision(your_value.to_f, :precision => 13) 
+0

ありがとうDimitri、それはデータベースに保存する前にフロートに変換するように見える方法です。 'number_with_precision'メソッドはビューヘルパーです。これはモデルでは使用できませんので、それが役に立たないと思います。 – Cimm