remove references rails not migrations false empty create active ruby-on-rails types floating-point decimal rails-activerecord

ruby on rails - references - Flotante vs decimal en ActiveRecord



rails migration null false (3)

En Rails 3.2.18,: decimal se convierte en: entero cuando se usa SQLServer, pero funciona bien en SQLite. Cambiar a: float resolvió este problema para nosotros.

La lección aprendida es "¡siempre use bases de datos homogéneas de desarrollo y despliegue!"

A veces, los tipos de datos de Activerecord me confunden. Err, a menudo. Una de mis preguntas eternas es, para un caso dado,

¿Debo usar :decimal o :float ?

A menudo he encontrado este enlace, ActiveRecord:: decimal vs: float? , pero las respuestas no son lo suficientemente claras para estar seguro:

He visto muchos hilos en los que la gente recomienda no usar nunca flotante y siempre usar decimales. También he visto sugerencias de algunas personas para usar el flotador solo para aplicaciones científicas.

Aquí hay algunos ejemplos de casos:

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

He usado :decimal en el pasado, pero encontré que tratar con objetos BigDecimal en Ruby era innecesariamente incómodo en comparación con un flotador. También sé que puedo usar :integer para representar dinero / centavos, por ejemplo, pero no es adecuado para otros casos, por ejemplo, cuando cantidades en las que la precisión podría cambiar con el tiempo.

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

En Rails 4.1.0, he enfrentado un problema con el ahorro de latitud y longitud en la base de datos MySql. No se puede guardar un número de fracción grande con el tipo de datos flotante. Y cambio el tipo de datos a decimal y trabajando para mí.

def change change_column :cities, :latitude, :decimal, :precision => 15, :scale => 13 change_column :cities, :longitude, :decimal, :precision => 15, :scale => 13 end


Recuerdo que mi profesor de CompSci me dijo que nunca usara flotadores como moneda.

La razón de ello es cómo la especificación IEEE define flotantes en formato binario. Básicamente, almacena signo, fracción y exponente para representar un flotador. Es como una notación científica para binario (algo como +1.43*10^2 ). Debido a eso, es imposible almacenar fracciones y decimales exactamente en Float.

Por eso hay un formato decimal. Si haces esto:

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

mientras que si solo haces

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

Entonces, si estás tratando con pequeñas fracciones, como intereses compuestos, o tal vez incluso con una geolocalización, recomendaría el formato decimal, ya que en formato decimal 1.0/10 es exactamente 0.1.

Sin embargo, debe tenerse en cuenta que, a pesar de ser menos precisos, los flotadores se procesan más rápido. Aquí hay 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

Responder

Usa el flotador cuando no te importa demasiado la precisión. Por ejemplo, algunas simulaciones y cálculos científicos solo necesitan hasta 3 o 4 dígitos significativos. Esto es útil para cambiar la precisión por velocidad. Ya que no necesitan precisión tanto como velocidad, usarían flotador.

Use el decimal si está tratando con números que necesitan ser precisos y resuma el número correcto (como intereses compuestos y cosas relacionadas con el dinero). Recuerde: si necesita precisión, siempre debe usar decimal.