【发布时间】:2014-09-25 03:33:37
【问题描述】:
假设我有以下代码:
x = 0.8
y = 1.0
检查y 是否等同于Integer 的最佳方法是什么?目前我正在做:
y.to_int == y
这行得通,但我觉得应该有更好的方法。
【问题讨论】:
标签: ruby type-conversion
假设我有以下代码:
x = 0.8
y = 1.0
检查y 是否等同于Integer 的最佳方法是什么?目前我正在做:
y.to_int == y
这行得通,但我觉得应该有更好的方法。
【问题讨论】:
标签: ruby type-conversion
你mod的值是1,检查值是否等于0。
if y % 1 == 0
【讨论】:
一般来说,当你不关心数字类型时,你应该使用==来比较数字,这应该是大多数时候。当你真正关心类型时,你应该使用继承自 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
【讨论】:
您可能甚至不想这样做。浮点运算会受到舍入误差的影响,并且您会认为会给出一系列操作,例如6.0 实际上可能会给出 5.9999999999999 。在这种情况下,任何检查该值是否为整数都会失败,即使您可能希望它成功。
通常,将浮点数与给定精度内的整数版本进行比较是一种更好的方法,例如if (x - x.to_i).abs < 0.001。
【讨论】:
(x * 4) % 1 == 0)。