Perché la divisione in Ruby restituisce un numero intero anziché un valore decimale?


256

Per esempio:

9 / 5  #=> 1

ma mi aspettavo 1.8. Come posso ottenere il risultato decimale corretto (non intero)? Perché sta tornando 1?


4
Si noti che se si utilizza effettivamente un metodo per restituire questo valore, non è necessario assegnarlo a una variabile; def method; a - b/8; endrestituirebbe semplicemente il risultato del calcolo dal metodo, poiché l'ultima espressione in una chiamata di metodo è il valore restituito.
Phrogz,

Risposte:


268

Sta facendo una divisione intera. Puoi creare uno dei numeri a Floataggiungendo .0:

9.0 / 5  #=> 1.8
9 / 5.0  #=> 1.8

10
Funziona ma la risposta to_f di seguito sembra più utile. To_f è più idiomatico in Ruby?
notapatch

9
La .to_frisposta è migliore se stai dividendo due variabili che contengono numeri interi, ad es a.to_f / b. Se stai letteralmente dividendo due numeri interi (che probabilmente è strano), allora usare 9.0 / 5va bene.
jefflunt,

350

Sta facendo una divisione intera. Puoi usare to_fper forzare le cose in modalità virgola mobile:

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

Questo funziona anche se i tuoi valori sono variabili anziché letterali. La conversione di un valore in float è sufficiente per forzare l'intera espressione in aritmetica in virgola mobile.


1
Questa è la risposta più "rotaie" rispetto alla risposta accettata.
Sean Ryan,

@muistooshort: non posso replicarlo, scusa. Probabilmente stavo facendo qualcosa di sbagliato.
Joao Costa,

4
@SeanRyan Perché specificamente Rails piuttosto che Ruby in generale? Non vedo perché uno sviluppatore (Ruby on) Rails dovrebbe fare questa cosa specifica in modo diverso da uno sviluppatore Ruby generale. Forse sto solo cercando di seminare la semantica e la maggior parte delle persone vede (Ruby su) Rails e Ruby come sinonimi in casi come questo.
Chinoto Vokro,

169

C'è anche il Numeric#fdivmetodo che puoi usare invece:

9.fdiv(5)  #=> 1.8

1
Questo è il metodo più veloce che ho testato, l'unico modo per ottenere più prestazioni è dividere gli operandi che sono float per cominciare. Ho creato un generatore di numeri primi in Ruby per apprendere la sintassi, ora lo sto ottimizzando per sapere cosa funziona meglio. Ecco il punto di riferimento che ho messo insieme: require 'Base64; require 'zlib'; puts Zlib.inflate (Base64.decode64 ( "eJxlkMEOwiAQRO98hekFuGzxQEwPXvwR01ZqiYHqBk2Tln8XDlWgnDbM25nJonq9NaoD7ZTtR9PigxK09zM7AkgRHieXTYHOsBNf1nklM6B6TuhYpdp + rPgSdiCOi / d / kQ71QBOtAVFLEDly05 + UYQ2H + MckL6z0zioDdJG1S9K1K4iQAW66DhnmiqRYKEJFXMByux + XuOJ2XdO60dKsjC7aBtyTL5O5hLk ="))
Chinoto Vokro

Una domanda, manterrebbe la precisione come se usassimo "decimale"?
Adam Aiken,

39

Puoi verificarlo con irb:

$ irb
>> 2 / 3
=> 0
>> 2.to_f / 3
=> 0.666666666666667
>> 2 / 3.to_f
=> 0.666666666666667

26

Puoi includere il mathnmodulo ruby .

require 'mathn'

In questo modo, sarai in grado di effettuare la divisione normalmente.

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

In questo modo, si ottiene la divisione esatta (classe Rational) fino a quando non si decide di applicare un'operazione che non può essere espressa come razionale, ad esempio Math.sin.


1
Il modulo matematico è obsoleto dal rubino 2.2
Meier


6

Fixnum # to_r non è menzionato qui, è stato introdotto dal ruby ​​1.9. Converte Fixnum in forma razionale. Di seguito sono riportati alcuni esempi dei suoi usi. Questo può anche dare una divisione esatta fintanto che tutti i numeri utilizzati sono Fixnum.

 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

Esempio in cui un float operato su un numero razionale copre il risultato in float.

a = 5.to_r   #=> (5/1) 
a = a * 5.0  #=> 25.0 
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.