[解決済み】ActiveRecordのFloatとDecimalの比較
質問
Activerecordのデータ型に戸惑うことがあります。いや、よくあることです。私の永遠の疑問の1つは、あるケースについてです。
を使うべきでしょうか?
:decimal
または:float
?
このリンクによく出くわしました。 ActiveRecord: :decimal vs :float? しかし、その答えは、私が確信できるほど明確ではありません。
というスレッドをよく見かけます。 floatを使用し、常に10進数を使用します。また、いくつかの提案も目にしました。 科学的な用途にのみfloatを使用するようにとのことです。
以下はその例です。
-
ジオロケーション/緯度/経度。
-45.756688
,120.5777777
, ... -
比率/パーセンテージ。
0.9
,1.25
,1.333
,1.4143
, ...
私は
:decimal
を扱うのは大変でした。
BigDecimal
オブジェクトは、float に比べて不必要に厄介です。また
:integer
は、たとえばお金やセントを表現するのに使いますが、他のケース、たとえば時間の経過とともに精度が変化するような量には、あまり適していません。
- それぞれを使うメリット/デメリットは何ですか?
- どのタイプを使うべきか、経験則として何か良い方法はありますか?
どのように解決するのですか?
CompSciの教授が通貨にfloatを使うなと言っていたのを覚えています。
その理由は、どのように
IEEE仕様では浮動小数点が定義されている
を2進数で表したものです。基本的には、符号、分数、指数を格納してFloatを表現します。バイナリの科学的記数法のようなものです(以下のようなものです)。
+1.43*10^2
). そのため、Floatに分数や小数を正確に格納することは不可能です。
だからDecimal形式があるのです。こうすれば
irb:001:0> "%.47f" % (1.0/10)
=> "0.10000000000000000555111512312578270211815834045" # not "0.1"!
とするのに対して
irb:002:0> (1.0/10).to_s
=> "0.1" # the interprer rounds the number for you
ですから、複利のような小さな分数を扱う場合、あるいは地理的な位置情報を扱う場合は、10進数形式を強くお勧めします。
1.0/10
はちょうど0.1です。
ただし、精度が低いにもかかわらず、浮動小数点数の方が処理速度が速いことには注意が必要です。以下はベンチマークです。
require "benchmark"
require "bigdecimal"
d = BigDecimal.new(3)
f = Float(3)
time_decimal = Benchmark.measure{ (1..10000000).each { |i| d * d } }
time_float = Benchmark.measure{ (1..10000000).each { |i| f * f } }
puts time_decimal
#=> 6.770960 seconds
puts time_float
#=> 0.988070 seconds
回答
使用方法 フロート は、あまり精度を気にしない場合です。例えば、科学的なシミュレーションや計算では、有効数字が3桁か4桁までしか必要ない場合があります。これは、精度とスピードをトレードオフするのに有効です。速さほど精度を必要としないので、floatを使うのでしょう。
使用方法 10進数 正確な数字が必要な場合(複利やお金に関すること)。正確さが必要な場合は、常に10進数を使用することを忘れないでください。
関連
-
[解決済み] サーバーはRailsで既に稼働している
-
[解決済み] 文字列をfloatやintにパースするにはどうしたらいいですか?
-
[解決済み] .NETでのdecimal, float, doubleの違い?
-
[解決済み] 文字列が数値(float)であるかどうかを確認するにはどうすればよいですか?
-
[解決済み] Javaで数値を小数点以下n桁に丸める方法
-
[解決済み] 通貨を表すのにDoubleやFloatを使ってはいけないのですか?
-
[解決済み] HTML5でfloat入力タイプはありますか?
-
[解決済み] 10進数のrange()ステップ値を使用するには?
-
[解決済み] C#でDecimalをDoubleに変換する方法は?
-
[解決済み】常に小数点以下2桁を表示する数値の書式設定
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】PG::ConnectionBad: fe_sendauth: パスワードが供給されない
-
[解決済み] Mac OS Xにhomebrewがインストールされているかどうかを確認する方法
-
[解決済み] rake db:migrateを使って1ステップだけロールバックする方法
-
[解決済み] Ruby on rails "No route matches" (ルートに一致するものがない)。
-
[解決済み] erbでコメントを追加する最適な方法
-
[解決済み] rails consoleを起動するとRailsのイニシャライザーが呼ばれる?
-
[解決済み] レイル 4 radio_button_tag default not selected
-
[解決済み] Railsでグループとカウント
-
[解決済み] Rails 4: 利用可能なデータ型のリスト
-
[解決済み] Rails 3 datatypes?