Por que a divisão no Ruby está retornando um número inteiro em vez do valor decimal?

256

Por exemplo:

9 / 5  #=> 1

mas eu esperava 1.8. Como posso obter o resultado decimal (não inteiro) correto? Por que está voltando 1?

ErwinM
fonte
4
Observe que, se você estiver realmente usando um método para retornar esse valor, não precisará atribuí-lo a uma variável; simplesmente def method; a - b/8; endretornaria o resultado do cálculo do método, pois a última expressão em uma chamada de método é o valor de retorno.
#

Respostas:

268

Está fazendo divisão inteira. Você pode transformar um dos números a Floatadicionando .0:

9.0 / 5  #=> 1.8
9 / 5.0  #=> 1.8
vees
fonte
10
Isso funciona, mas a resposta to_f abaixo parece mais útil. To_f é mais idiomático em Ruby?
Notapatch 1/1
9
A .to_fresposta é melhor se você estiver dividindo duas variáveis ​​que contêm números inteiros, por exemplo a.to_f / b. Se você está literalmente dividindo dois números inteiros codificados (o que provavelmente é estranho), usar 9.0 / 5é bom.
precisa saber é
350

Está fazendo divisão inteira. Você pode usar to_fpara forçar as coisas ao modo de ponto flutuante:

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

Isso também funciona se seus valores forem variáveis ​​em vez de literais. Converter um valor em um float é suficiente para coagir toda a expressão à aritmética de ponto flutuante.

mu é muito curto
fonte
1
Esta é a resposta mais "trilhos" do que a resposta aceita.
Sean Ryan
@muistooshort: não consigo replicar, desculpe. Eu provavelmente estava fazendo algo errado.
João Costa
4
@SeanRyan Por que especificamente o Rails e não o Ruby em geral? Não vejo por que um desenvolvedor do Rails (Ruby on) faria essa coisa específica de maneira diferente do que um desenvolvedor geral do Ruby. Talvez eu esteja apenas detalhando a semântica e a maioria das pessoas apenas veja (Ruby on) Rails e Ruby como sinônimos em casos como este.
Chinoto Vokro 27/07
169

Há também o Numeric#fdivmétodo que você pode usar:

9.fdiv(5)  #=> 1.8
Konrad Reiche
fonte
1
Este é o método mais rápido que testei, a única maneira de obter mais desempenho é dividir operandos que são flutuadores. Criei um gerador de números primos no Ruby para aprender a sintaxe, agora estou otimizando para aprender o que funciona melhor. Aqui está o ponto de referência que eu juntos: require 'base64'; require 'zlib'; puts Zlib.inflate (Base64.decode64 ( "eJxlkMEOwiAQRO98hekFuGzxQEwPXvwR01ZqiYHqBk2Tln8XDlWgnDbM25nJonq9NaoD7ZTtR9PigxK09zM7AkgRHieXTYHOsBNf1nklM6B6TuhYpdp + rPgSdiCOi / d / kQ71QBOtAVFLEDly05 + UYQ2H + MckL6z0zioDdJG1S9K1K4iQAW66DhnmiqRYKEJFXMByux + XuOJ2XdO60dKsjC7aBtyTL5O5hLk ="))
Chinoto Vokro
Uma pergunta, seria preservar a precisão como estamos usando 'decimal'?
Adam Aiken
39

Você pode verificá-lo com o irb:

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

Você pode incluir o mathnmódulo ruby .

require 'mathn'

Dessa forma, você poderá fazer a divisão normalmente.

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

Dessa forma, você obtém a divisão exata (classe Rational) até decidir aplicar uma operação que não pode ser expressa como racional, por exemplo Math.sin.

Rok Kralj
fonte
1
O módulo mathn está obsoleto desde ruby ​​2.2
Meier
11

Mude 5para 5.0. Você está recebendo divisão inteira.

Tyler Eaves
fonte
6

O Fixnum # to_r não é mencionado aqui, foi introduzido desde o ruby ​​1.9. Converte Fixnum em forma racional. Abaixo estão exemplos de seus usos. Isso também pode fornecer uma divisão exata, desde que todos os números usados ​​sejam 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

Exemplo em que um flutuador operado em um número racional cobre o resultado para flutuar.

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