检查Float是否等效于Ruby中的整数值

说我有以下代码:

x = 0.8 y = 1.0 

检查y是否相当于Integer的最佳方法是什么? 目前我正在做:

 y.to_int == y 

哪个有效,但我觉得应该有更好的方法。

您将值修改为1,并检查该值是否等于0。

 if y % 1 == 0 

你可能甚至不想那样做。 浮点运算会受到舍入误差的影响,您认为给出的一系列操作例如6.0实际上可能会给出5.9999999999999。 在这种情况下,任何检查值为整数的都将失败,即使您可能希望它成功。 通常,将float与给定精度内的整数版本进行比较是一种更好的方法,例如if (x - x.to_i).abs < 0.001

TL; DR

通常,当您不关心数字类型时,您应该使用==来比较数字,这应该是大部分时间。 当你真的关心类型时,你应该使用从Numeric#eqlinheritance的对象相等比较? 。

可能有效的最简单的事情

你可以问一个数字对象,如果它是一个整数。 例如, Numeric#integer? 让你让一个数字来检查自己并返回一个布尔值:

 [1, 1.2, 1.02e+1].map(&:integer?) #=> [true, false, false] 

如果你只关心y是否是一个整数,那么这就是你要走的路。 使用您自己的示例:

 y = 1 y.integer? #=> true y = 1.0 y.integer? #=> false 

其他方案

如果你正在尝试做一些更复杂的事情,比如试图在平等比较中避免自动数字类型转换,那么唯一真正的限制就是你的想象力和你试图在代码中清楚表达的想法。 Numeric,Float,Integer,Object,String和其他类中有许多方法可以执行类型对话和严格的相等比较。 以下是一些例子。

使用#eql?

使用各种方法转换为Integer,然后检查严格的对象相等性:

 y = 1.2 # All of these will return false. y.eql? y.truncate y.eql? y.floor y.eql? y.to_i y.eql? Integer(y) 

用#zero检查余数?

如果要创建一个没有==自动数值转换的布尔表达式,可以使用从Numeric#zeroinheritance的特定于类的方法? 。 例如:

 (y % 1).zero? y.modulo(1).zero? 

将#ceil或#floor与减法一起使用

如果modulo对某些类型的数字不起作用,那么你可以使用Float#ceil或Float#floor :

 y = 1.2 (y - y.floor).zero? #=> false y = 1.02e+1 (y.floor - y).zero? #=> false