144 votos

Float vs Decimal en ActiveRecord

A veces, Activerecord tipos de datos de confundirme. Err, a menudo. Una de mis eternas preguntas, es decir, para un caso determinado,

Debo usar :decimal o :float?

He vienen a menudo a través de este enlace, ActiveRecord: :decimal vs :float?, pero las respuestas no son lo suficientemente claro para mí, para estar seguro:

He visto muchos hilos donde la gente recomendar el plano para no usar nunca float y siempre uso decimal. También he visto las sugerencias por parte de algunos la gente a usar flotador para aplicaciones científicas sólo.

Aquí hay algunos ejemplos de los casos:

  • Geolocalización/latitud/longitud: -45.756688, 120.5777777, ...
  • Proporción/porcentaje: 0.9, 1.25, 1.333, 1.4143, ...

He utilizado :decimal en el pasado, pero me pareció que ocupan BigDecimal objetos en Ruby era demasiado torpe en comparación con un flotador. También sé que puedo usar :integer que representan dinero/centavos, por ejemplo, pero no encaja para otros casos, por ejemplo, cuando las cantidades en las que la precisión podría cambiar con el tiempo.

  • ¿Cuáles son las ventajas/desventajas del uso de cada uno de ellos?
  • ¿Cuáles serían algunas buenas reglas de oro para saber qué tipo de uso?

219voto

Iuri G. Puntos 3809

Recuerdo que mi CompSci profesor diciendo: nunca el uso de la flota de la moneda.

La razón de esto es cómo la especificación IEEE define flota en formato binario. Básicamente, tiendas de signo, la fracción y el exponente a representar un Float. Es como una notación científica para el binario (algo como +1.43*10^2). Debido a eso, es imposible guardar las fracciones y los decimales en sistema Flotante exactamente.

Es por eso que existe un formato Decimal. Si haces esto:

irb:001:0> "%.47f" % (1.0/10)
=> "0.10000000000000000555111512312578270211815834045" # not "0.1"!

mientras que si usted acaba de hacer

irb:002:0> (1.0/10).to_s
=> "0.1" # the interprer rounds the number for you

Así que si usted está tratando con pequeñas fracciones, como la capitalización de intereses, o tal vez incluso de geolocalización, recomiendo el formato Decimal, ya que en formato decimal 1.0/10 es exactamente 0.1.

Sin embargo, cabe señalar que a pesar de ser menos preciso, los flotadores se procesan más rápido. He aquí un punto de referencia:

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

Respuesta

El uso de flotación cuando no se preocupan por la precisión demasiado. Por ejemplo, algunos científicos simulaciones y cálculos sólo necesitan hasta 3 o 4 dígitos significativos. Esto es útil en el comercio de precisión para la velocidad. Ya que no necesitan de precisión tanto como la velocidad, que haría uso de la flotación.

El uso de decimales , si se trata de números que tienen que ser precisos y suma hasta el número correcto (como la capitalización de intereses y de dinero relacionado con las cosas). Recuerde: si necesita precisión, entonces usted debe utilizar siempre decimal.

5voto

ryan0 Puntos 639

En Rails 3.2.18, :decimal se convierte en :integer cuando el uso de SQLServer, pero funciona bien en SQLite. Cambiar a :float resuelto este problema para nosotros.

La lección aprendida es "utilizar siempre homogénea de desarrollo y de implementación de bases de datos!"

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X