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?


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

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.


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

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

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.


1
O módulo mathn está obsoleto desde ruby ​​2.2
Meier


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 
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.