Flotador de redondeo en rubí

150

Tengo problemas para redondear. Tengo un flotador, que quiero redondear a la centésima de un decimal. Sin embargo, solo puedo usar lo .roundque básicamente lo convierte en un int, lo que significa que 2.34.round # => 2. hay una manera simple de hacer algo como2.3465 # => 2.35

usuario211662
fuente

Respuestas:

181

Al mostrar, puede usar (por ejemplo)

>> '%.2f' % 2.3465
=> "2.35"

Si desea almacenarlo redondeado, puede usar

>> (2.3465*100).round / 100.0
=> 2.35
Peter
fuente
2
Gracias. No me di cuenta de que Sprintf se encargaría de redondear por mí. sprintf '%.2f', 2.3465También funciona.
Noah Sussman
66
value.round (2) es mejor que esta solución
Kit Ho
12
Tenga en cuenta que 2.3000.round(2) => 2.3y sprintf '%.2f', 2.300 => 2.30. En mi opinión, esta es una falla en round (), o debería tener una opción para preservar los ceros finales.
Excalibur
14
@Excalibur 2.3000.round(2)es un número, no una cadena. No hay forma de que el número 2.3sea ​​diferente 2.30, por lo que no hay forma de tener una opción para preservar los ceros finales. Podrías hacer tu propia clase de números_con_significancia pero entonces ya tenemos cadenas.
Roobie Nuby
66
Tenga en cuenta que aunque esto hace el trabajo de dos cifras decimales, hay un defecto en '%.3f' % 1.2345(3 lugares decimales, no 2), sin embargo !! Lo mismo para sprintftambién. Tener cuidado. Eso va a volver => 1.234 , no => 1.235 como la mayoría esperaría (OIA, después de que el segundo decimal, rondas sprintf 5 hacia abajo y sólo un 6 rondas arriba). Es por eso que el comentario anterior de Kit Ho tiene más de 25 votos a favor. Es más seguro de usar, '%.3f' % 1.2345.round(3)por lo que el número se redondea correctamente .roundprimero, luego se formatea (con ceros finales, si es necesario).
likethesky
392

Pase un argumento a redondear que contenga el número de decimales a redondear

>> 2.3465.round
=> 2
>> 2.3465.round(2)
=> 2.35
>> 2.3465.round(3)
=> 2.347
Steve Weet
fuente
8
Esto parecería más sensato que multiplicar, redondear y dividir. +1
Mark Embling
3
Hmm, este método no parece estar en ruby ​​1.8.7. Tal vez en 1.9?
Brian Armstrong
2
@Brian. Esto definitivamente está en 1.9 y también está en rieles (con lo que esta pregunta fue etiquetada)
Steve Weet
3
El método de redondeo de Ruby 1.8.7 no tiene esta habilidad, agregar el parámetro de redondeo de lugar decimal es una habilidad 1.9
bobmagoo
1
Tenga en cuenta que no obtiene ceros finales con esto, por lo que 1.1.round(2)=> 1.1no1.10
NotAnAmbiTurner
9

puede usar esto para redondear a una precisión.

//to_f is for float

salary= 2921.9121
puts salary.to_f.round(2) // to 2 decimal place                   

puts salary.to_f.round() // to 3 decimal place          
bollo tecnológico
fuente
7

Puede agregar un método en Float Class, lo aprendí de stackoverflow:

class Float
    def precision(p)
        # Make sure the precision level is actually an integer and > 0
        raise ArgumentError, "#{p} is an invalid precision level. Valid ranges are integers > 0." unless p.class == Fixnum or p < 0
        # Special case for 0 precision so it returns a Fixnum and thus doesn't have a trailing .0
        return self.round if p == 0
        # Standard case  
        return (self * 10**p).round.to_f / 10**p
    end
end
Albert Català
fuente
3

También puede proporcionar un número negativo como argumento del roundmétodo para redondear al múltiplo más cercano de 10, 100 y así sucesivamente.

# Round to the nearest multiple of 10. 
12.3453.round(-1)       # Output: 10

# Round to the nearest multiple of 100. 
124.3453.round(-2)      # Output: 100
BrunoFacca
fuente
2
def rounding(float,precision)
    return ((float * 10**precision).round.to_f) / (10**precision)
end
PeteJLeonard
fuente
2

¿qué pasa (2.3465*100).round()/100.0?

thenoviceoof
fuente
1

Si solo necesita mostrarlo, usaría el ayudante number_with_precision . Si lo necesita en otro lugar, usaría, como señaló Steve Weet, el roundmétodo

Fer
fuente
1
Tenga en cuenta que number_with_precisiones un método exclusivo de Rails.
Smar
0

Para ruby ​​1.8.7 puede agregar lo siguiente a su código:

class Float
    alias oldround:round
    def round(precision = nil)
        if precision.nil?
            return self
        else
            return ((self * 10**precision).oldround.to_f) / (10**precision)
        end 
    end 
end
Robert
fuente