Скажем, у меня есть следующий код:
x = 0.8
y = 1.0
Какой лучший способ проверить, что y
эквивалентен Integer
? На данный момент я делаю:
y.to_int == y
который работает, но я чувствую, что должен быть лучший способ.
Скажем, у меня есть следующий код:
x = 0.8
y = 1.0
Какой лучший способ проверить, что y
эквивалентен Integer
? На данный момент я делаю:
y.to_int == y
который работает, но я чувствую, что должен быть лучший способ.
Вы mod
значение с 1 и убедитесь, что значение равно 0.
if y % 1 == 0
Вы, вероятно, даже не хотите этого делать. Арифметика с плавающей точкой подвержена ошибкам округления, и ряд операций, которые вы, например, думаете, дает, например, 6.0 может фактически дать 5.9999999999999. В этом случае любая проверка того, что значение является целым, не удастся, даже если вы, вероятно, намеревались добиться успеха.
Обычно это лучший подход для сравнения float с целочисленной версией с заданной точностью, например if (x - x.to_i).abs < 0.001
.
Как правило, вы должны использовать ==
для сравнения чисел, когда вам не нужен цифровой тип, который должен быть в большинстве случаев. Когда вы действительно заботитесь о типе, вы должны использовать сравнение объектного равенства, унаследованное от NumeriС# eql?.
Вы можете просто запросить числовой объект, если это целое число. Например, NumeriС# 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)
Если вы хотите создать логическое выражение без автоматических числовых преобразований, сделанных с помощью ==
, вы можете использовать метод класса, унаследованный от NumeriС# zero?. Например:
(y % 1).zero?
y.modulo(1).zero?
Если modulo не делает трюк для вас с определенными типами чисел, вы можете использовать Float # ceil или Float # floor:
y = 1.2
(y - y.floor).zero?
#=> false
y = 1.02e+1
(y.floor - y).zero?
#=> false