Warum gibt die Division in Ruby eine Ganzzahl anstelle eines Dezimalwerts zurück?

256

Beispielsweise:

9 / 5  #=> 1

aber ich habe erwartet 1.8. Wie kann ich das richtige Dezimalergebnis (nicht ganzzahlig) erhalten? Warum kehrt es 1überhaupt zurück?

ErwinM
quelle
4
Beachten Sie, dass Sie diesen Wert keiner Variablen zuweisen müssen, wenn Sie ihn tatsächlich mit einer Methode zurückgeben. def method; a - b/8; endwürde einfach das Ergebnis der Berechnung von der Methode zurückgeben, da der letzte Ausdruck in einem Methodenaufruf der Rückgabewert ist.
Phrogz

Antworten:

268

Es macht eine ganzzahlige Division. Sie können eine der Zahlen a machen, Floatindem Sie Folgendes hinzufügen .0:

9.0 / 5  #=> 1.8
9 / 5.0  #=> 1.8
vees
quelle
10
Dies funktioniert, aber die Antwort to_f unten scheint nützlicher zu sein. Ist to_f in Ruby idiomatischer?
Notapatch
9
Die .to_fAntwort ist besser, wenn Sie zwei Variablen teilen, die Ganzzahlen enthalten, z a.to_f / b. Wenn Sie buchstäblich zwei fest codierte Ganzzahlen teilen (was wahrscheinlich seltsam ist), ist die Verwendung 9.0 / 5in Ordnung.
Jefflunt
350

Es macht eine ganzzahlige Division. Sie können verwenden to_f, um Dinge in den Gleitkommamodus zu zwingen:

9.to_f / 5  #=> 1.8
9 / 5.to_f  #=> 1.8

Dies funktioniert auch, wenn Ihre Werte Variablen anstelle von Literalen sind. Das Konvertieren eines Werts in ein Gleitkomma reicht aus, um den gesamten Ausdruck in Gleitkomma-Arithmetik zu zwingen.

mu ist zu kurz
quelle
1
Dies ist die Antwort "mehr Schienen" als die akzeptierte Antwort.
Sean Ryan
@ Muistooshort: Ich kann es nicht replizieren, sorry. Ich habe wahrscheinlich etwas falsch gemacht.
Joao Costa
4
@ SeanRyan Warum speziell Rails statt Ruby im Allgemeinen? Ich verstehe nicht, warum ein (Ruby on) Rails-Entwickler diese spezielle Sache anders machen würde als ein allgemeiner Ruby-Entwickler. Vielleicht wähle ich nur die Semantik aus und die meisten Leute sehen (Ruby on) Rails und Ruby in solchen Fällen auch als synonym.
Chinoto Vokro
169

Es gibt auch die Numeric#fdivMethode, die Sie stattdessen verwenden können:

9.fdiv(5)  #=> 1.8
Konrad Reiche
quelle
1
Dies ist die schnellste Methode, die ich getestet habe. Die einzige Möglichkeit, mehr Leistung zu erzielen, besteht darin, Operanden zu teilen, die zunächst Floats sind. Ich habe in Ruby einen Primzahlengenerator erstellt, um die Syntax zu lernen. Jetzt optimiere ich ihn, um herauszufinden, was am besten funktioniert. Hier ist die Benchmark ich zusammen: require 'base64'; require 'zlib'; Puts Zlib.inflate (Base64.decode64 ( "eJxlkMEOwiAQRO98hekFuGzxQEwPXvwR01ZqiYHqBk2Tln8XDlWgnDbM25nJonq9NaoD7ZTtR9PigxK09zM7AkgRHieXTYHOsBNf1nklM6B6TuhYpdp + rPgSdiCOi / d / kQ71QBOtAVFLEDly05 + UYQ2H + MckL6z0zioDdJG1S9K1K4iQAW66DhnmiqRYKEJFXMByux + XuOJ2XdO60dKsjC7aBtyTL5O5hLk ="))
Chinoto Vokro
Eine Frage, würde es die Genauigkeit bewahren, wie wir 'Dezimal' verwenden?
Adam Aiken
39

Sie können es mit irb überprüfen:

$ irb
>> 2 / 3
=> 0
>> 2.to_f / 3
=> 0.666666666666667
>> 2 / 3.to_f
=> 0.666666666666667
Renaud
quelle
26

Sie können das Ruby- mathnModul einschließen .

require 'mathn'

Auf diese Weise können Sie die Aufteilung normal vornehmen.

1/2              #=> (1/2)
(1/2) ** 3       #=> (1/8)
1/3*3            #=> 1
Math.sin(1/2)    #=> 0.479425538604203

Auf diese Weise erhalten Sie eine exakte Division (Klasse Rational), bis Sie sich entscheiden, eine Operation anzuwenden, die beispielsweise nicht als rational ausgedrückt werden kann Math.sin.

Rok Kralj
quelle
1
Das Mathn-Modul ist seit Ruby 2.2
Meier
11

Ändern Sie das 5in 5.0. Sie erhalten eine ganzzahlige Division.

Tyler Eaves
quelle
6

Fixnum # to_r wird hier nicht erwähnt, es wurde seit Ruby 1.9 eingeführt. Es wandelt Fixnum in eine rationale Form um. Nachfolgend finden Sie Beispiele für seine Verwendung. Dies kann auch eine genaue Unterteilung ergeben, solange alle verwendeten Zahlen Fixnum sind.

 a = 1.to_r  #=> (1/1) 
 a = 10.to_r #=> (10/1) 
 a = a / 3   #=> (10/3) 
 a = a * 3   #=> (10/1) 
 a.to_f      #=> 10.0

Beispiel, bei dem ein Float, der mit einer rationalen Zahl betrieben wird, das schwebende Ergebnis verdeckt.

a = 5.to_r   #=> (5/1) 
a = a * 5.0  #=> 25.0 
ucpuzz
quelle