Rundschwimmer in Ruby


150

Ich habe Probleme beim Runden. Ich habe einen Float, den ich auf die Hundertstel Dezimalstelle runden möchte. Ich kann jedoch nur verwenden, .roundwas es im Grunde in ein int verwandelt, was bedeutet, dass 2.34.round # => 2. es einen einfachen Effekt gibt, um so etwas zu tun2.3465 # => 2.35

Antworten:


181

Bei der Anzeige können Sie (zum Beispiel) verwenden

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

Wenn Sie es gerundet speichern möchten, können Sie verwenden

>> (2.3465*100).round / 100.0
=> 2.35

2
Vielen Dank. Ich wusste nicht, dass Sprintf sich um mich kümmern würde. sprintf '%.2f', 2.3465funktioniert auch.
Noah Sussman

66
value.round (2) ist besser als diese Lösung
Kit Ho

12
Denken Sie daran, dass 2.3000.round(2) => 2.3und sprintf '%.2f', 2.300 => 2.30. Meiner Meinung nach ist dies ein Fehler in round (), oder es sollte eine Option geben, um nachgestellte Nullen beizubehalten.
Excalibur

14
@Excalibur 2.3000.round(2)ist eine Zahl, keine Zeichenfolge. Es gibt keine Möglichkeit, dass sich die Zahl von 2.3unterscheidet 2.30, daher gibt es keine Möglichkeit, nachfolgende Nullen beizubehalten. Sie könnten Ihre eigene Klasse von Zahlen mit Bedeutung erstellen, aber dann haben wir bereits Zeichenfolgen.
Roobie Nuby

6
Beachten Sie, dass dies zwar für zwei Dezimalstellen funktioniert, es jedoch einen Fehler gibt '%.3f' % 1.2345(3 Dezimalstellen, nicht 2) !! Gleiches gilt auch für sprintf. In acht nehmen. Das wird => 1.234 nicht => 1.235 so zurückkehren , wie die meisten erwarten würden (iow, nach der 2. Dezimalstelle, rundet sprintf 5 ab und rund 6 nur auf). Aus diesem Grund hat der Kommentar von Kit Ho oben mehr als 25 positive Stimmen. Sicherer zu verwenden, '%.3f' % 1.2345.round(3)daher wird die Zahl zuerst richtig gerundet .roundund dann formatiert (ggf. mit nachgestellten Nullen).
likethesky

392

Übergeben Sie ein Argument an round, das die Anzahl der Dezimalstellen enthält, auf die gerundet werden soll

>> 2.3465.round
=> 2
>> 2.3465.round(2)
=> 2.35
>> 2.3465.round(3)
=> 2.347

8
Dies erscheint sinnvoller als Multiplizieren, Runden und Teilen. +1
Mark Embling

3
Hmm, diese Methode scheint nicht in Ruby 1.8.7 zu sein. Vielleicht in 1.9?
Brian Armstrong

2
@ Brian. Dies ist definitiv in 1.9 und ist auch in Schienen (mit denen diese Frage markiert wurde)
Steve Weet

3
Ruby 1.8.7 Runde Methode hat diese Fähigkeit nicht, das Hinzufügen des Dezimalstellen-Rundungsparameters ist eine Fähigkeit 1.9
Bobmagoo

1
Beachten Sie, dass Sie damit keine nachgestellten Nullen erhalten, also 1.1.round(2)=> 1.1nicht1.10
NotAnAmbiTurner

9

Sie können dies zum Runden auf eine Präzision verwenden.

//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          

7

Sie können eine Methode in Float Class hinzufügen. Dies habe ich aus dem Stackoverflow gelernt:

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

3

Sie können auch eine negative Zahl als Argument für die roundMethode angeben, um auf das nächste Vielfache von 10, 100 usw. zu runden.

# 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

2
def rounding(float,precision)
    return ((float * 10**precision).round.to_f) / (10**precision)
end


1

Wenn Sie es nur anzeigen müssen, würde ich den Helfer number_with_precision verwenden . Wenn Sie es woanders brauchen, würde ich, wie Steve Weet betonte, die roundMethode anwenden


1
Beachten Sie, dass dies number_with_precisionnur eine Rails-Methode ist.
Smar

0

Für Ruby 1.8.7 können Sie Ihrem Code Folgendes hinzufügen:

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
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.