Tengo un modelo llamado Artículo, donde estoy actualizando el valor unit_price (el tipo de datos es decimal), actualmente no estoy poniendo ningún límite al almacenar el valor, almacenándolo tal como está. Pero ahora puedo ver este error de PG PG::NumericValueOutOfRange , cuando el valor excede el límite.
Así que solo estaba tratando de limitar el valor y verificar algo en la consola. A continuación se muestran los datos. (Aquí en los datos no estoy poniendo todos los valores decimales)
#<Item id: 167199, description: "192830139", category_id: 10327, unit_id: 5596, weight: 0.1e5, unit_price: 0.4083333333659917816764132553606237816656920077972709552126705653021442494641325536062378168e1 i = Item.find 167199 i.unit_price.to_f => 4.083333333659918 #<Item id: 167199, description: "192830139", category_id: 10327, unit_id: 5596, weight: 0.1e5, unit_price: 0.6511366980197836882065909262763993442019943880913510722934069011050182329156169820243980265070876781866034494363303661586489199452739290976143216266200531728395970406461889852558384421962422689303402903e-2 i.unit_price.to_f => 0.006511366980197837¿Puedo saber cuál será la razón por la que to_f reduce automáticamente el límite del decimal? ¿Cuál será la mejor manera de resolver este problema? Solo estaba pensando en truncar con algún límite.
¿Puedo saber cuál será la razón por la que to_f reduce automáticamente el límite del decimal?
El motivo es que los métodos to_f se utilizan para convertir objetos en Float s , que son números de punto flotante de precisión doble estándar de 64 bits . La precisión de estos números es limitada, por lo tanto, la precisión del objeto original debe reducirse automáticamente durante el proceso de conversión para que quepa en un Float . Toda precisión adicional se pierde.
Parece que está utilizando la clase BigDecimal . El método BigDecimal#to_f convertirá el objeto decimal de punto flotante de precisión arbitraria en un Float . Naturalmente, la información se perderá durante esta conversión si el gran decimal es más preciso que lo que permiten los Float . Esta conversión puede desbordarse o subdesbordarse si se exceden los límites.
Estaba pensando en algo truncado con algún límite.
Hay un método truncate si desea un control explícito sobre la precisión del resultado. No se producirá ningún tipo de redondeo, hay un método separado para eso .
BigDecimal#truncate
Elimina toda la parte fraccionaria del número, dejando solo un entero.
BigDecimal('3.14159').truncate #=> 3 BigDecimal#truncate(n)
Mantiene n dígitos de precisión, borra el resto.
BigDecimal('3.14159').truncate(3) #=> 3.141puede usar el método .truncate() incorporado de ruby
por ejemplo:
floatNum = 1.222222222222222 truncatedNum = floatNum.truncate(3) #3 is the number of decimal places you want puts floatNum #returns 1.222otra forma es usar el método .round()
por ejemplo: