说我有以下代码:
x = 0.8
y = 1.0
检查y
是否等同于Integer
的最佳方式是什么?目前我正在做:
y.to_int == y
有效,但我觉得应该有更好的方法。
答案 0 :(得分:65)
您{1}的值为{1},并检查该值是否等于0.
mod
答案 1 :(得分:3)
你可能根本不想这样做。浮点运算会受到舍入误差的影响,并且您会想到一系列操作,例如: 6.0实际上可能给5.9999999999999。在这种情况下,任何检查值为整数的都将失败,即使您可能希望它成功。
通常,将float与给定精度内的整数版本进行比较是更好的方法,例如if (x - x.to_i).abs < 0.001
。
答案 2 :(得分:3)
通常情况下,当您不关心数字类型时,应使用==
来比较数字,这应该是大部分时间。如果您确实关心类型,则应使用从Numeric#eql?继承的对象相等性比较。
如果它是一个整数,你可以问一个数字对象。例如,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和其他类中有许多方法可以执行类型对话和严格的相等比较。以下是一些例子。
使用各种方法转换为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)
如果要创建一个没有==
自动数字转换的布尔表达式,可以使用从Numeric#zero?继承的特定于类的方法。例如:
(y % 1).zero?
y.modulo(1).zero?
如果模数对某些类型的数字没有帮助,那么您可以使用Float#ceil或Float#floor:
y = 1.2
(y - y.floor).zero?
#=> false
y = 1.02e+1
(y.floor - y).zero?
#=> false