为什么Ruby中的除法返回整数而不是十进制值?


256

例如:

9 / 5  #=> 1

但我期望1.8。如何获得正确的十进制(非整数)结果?为什么它又回来1了?


4
请注意,如果您实际上使用的是一种方法来返回该值,则无需将其分配给变量。只需def method; a - b/8; end从方法中返回计算结果,因为方法调用中的最后一个表达式是返回值。
Phrogz

Answers:


268

它正在做整数除法。您可以Float通过添加.0以下数字之一:

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

10
这可行,但是下面的to_f答案似乎更有用。to_f在Ruby中更惯用吗?
notapatch 2015年

9
.to_f回答是更好,如果你将包含整数,例如两个变量a.to_f / b。如果您实际上是将两个硬编码的整数相除(可能很奇怪),那么使用9.0 / 5就可以了。
jefflunt

350

它正在做整数除法。您可以用来to_f将事物强制为浮点模式:

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

如果您的值是变量而不是文字,这也适用。将一个值转换为浮点数足以将整个表达式强制转换为浮点运算。


1
这是比公认的答案更“合理”的答案。
肖恩·瑞安

@muistooshort:对不起,我无法复制它。我可能做错了。
Joao Costa

4
@SeanRyan为什么一般来说特别是Rails而不是Ruby?我不明白为什么(在Ruby on上)Rails开发人员会与一般的Ruby开发人员以不同的方式进行此特定操作。也许我只是在挑剔语义,大多数人只是在这样的情况下将Rails和Ruby视为(Ruby on)同义词。
Chinoto Vokro '16

169

还有Numeric#fdiv一种方法可以代替使用:

9.fdiv(5)  #=> 1.8

1
这是我测试过的最快的方法,要获得更高的性能,唯一的方法是将以浮点数开头的操作数相除。为了了解语法,我在Ruby中构建了素数生成器,现在我对其进行优化以了解最有效的方法。下面是我放在一起基准:需要'的base64';要求'zlib的';看跌期权Zlib.inflate(Base64.decode64( “eJxlkMEOwiAQRO98hekFuGzxQEwPXvwR01ZqiYHqBk2Tln8XDlWgnDbM25nJonq9NaoD7ZTtR9PigxK09zM7AkgRHieXTYHOsBNf1nklM6B6TuhYpdp + rPgSdiCOi / d / kQ71QBOtAVFLEDly05 + UYQ2H + MckL6z0zioDdJG1S9K1K4iQAW66DhnmiqRYKEJFXMByux + XuOJ2XdO60dKsjC7aBtyTL5O5hLk =”))
Chinoto Vokro

一个问题,它会像我们使用“十进制”一样保留精度吗?
亚当·艾肯

39

您可以使用irb进行检查:

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

26

您可以包括ruby mathn模块。

require 'mathn'

这样,您将能够正常进行划分。

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

这样,您将获得精确的除法(Rational类),直到您决定应用无法表达为有理数的操作(例如)Math.sin


1
从ruby 2.2开始不推荐使用mathn模块
Meier


6

这里没有提到Fixnum#to_r,它是从ruby 1.9开始引入的。它将Fixnum转换为有理形式。以下是其用法示例。只要使用的所有数字均为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

以有理数运算的浮点数会将结果隐蔽为浮点数的示例。

a = 5.to_r   #=> (5/1) 
a = a * 5.0  #=> 25.0 
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.