ruby - truncamiento - Truncar un número de punto flotante sin redondear
truncar en excel (7)
Tengo un número de punto flotante que quiero truncar en 3 lugares pero no quiero redondear.
Por ejemplo, convierta 1.0155555555555555
a 1.015
(no 1.016
).
¿Cómo voy a hacer esto en Ruby?
Dado que Float#truncate
método Float#truncate
2.4 de ruby toma como argumento opcional una cantidad de dígitos decimales:
1.0155555555555555.truncate(3)
# => 1.015
Esta solución se basa en un brillante truco BigDecimal de @SidKrishnan, pero también puede manejar flotadores más grandes sin vacilar en problemas de precisión.
# Truncate a floating-point value without rounding up.
#
# trunc_float(1.999, 2) # => 1.99
# trunc_float(1.999, 0) # => 1.0
#
# @param value [Float]
# @param precision [Integer]
# @return [Float]
def trunc_float(value, precision)
BigDecimal(value.to_s).truncate(precision).to_f
end
#--------------------------------------- Test
describe ".trunc_float" do
def call(*args)
trunc_float(*args)
end
it "generally works" do
[
[[1, 0], 1.0],
[[1.999, 4], 1.999],
[[1.999, 3], 1.999],
[[1.999, 2], 1.99],
[[1.999, 1], 1.9],
[[1.999, 0], 1.0],
[[111111111.9999999, 3], 111111111.999],
[[1508675846.650976, 6], 1508675846.650976],
].each do |input, expected|
output = call(*input)
expect([input, output]).to eq [input, expected]
end
end
end
La respuesta de sid está bien, pero no cumple con el primer requisito y, por lo tanto, falla la prueba de Anwar. el requisito es que debemos comenzar sin procesar para que ruby no convierta el número fácilmente. y comenzar sin procesar como se obtiene sin procesar es utilizar una cadena simple, por lo que
> "59.99999999999999999999".to_d.truncate(2) => #BigDecimal:55a38a23cd68,''0.5999E2'',18(45)> > "59.99999999999999999999".to_d.truncate(2).to_s => "59.99" > "59.99999999999999999999".to_d.truncate(2).to_f => 59.99
solo compartiendo esto ahora, ya que me encontré con este problema hoy mismo:)
Multiplique por mil, el piso, divida por mil, asegurándose de hacer una división flotante.
(x * 1000).floor / 1000.0
O, en Ruby 1.9.2, usando una versión de round que no estaba disponible en versiones anteriores,
(x - 0.0005).round(3)
Puede hacerlo usando expresiones regulares, ya que ruby / rails tienen un límite de precisión.
- Primero convierte el número a cadena y luego sigue -
input = "114.9999999999999999999999"
entrada [/ / d +. / d /]
114.99
También puede convertir a BigDecimal y truncar en él.
1.237.to_d.truncate(2).to_f # will return 1.23