Подтвердить что ты не робот

Проверка, является ли Float эквивалентом целочисленного значения в Ruby

Скажем, у меня есть следующий код:

x = 0.8
y = 1.0

Какой лучший способ проверить, что y эквивалентен Integer? На данный момент я делаю:

y.to_int == y

который работает, но я чувствую, что должен быть лучший способ.

4b9b3361

Ответ 1

Вы mod значение с 1 и убедитесь, что значение равно 0.

if y % 1 == 0

Ответ 2

Вы, вероятно, даже не хотите этого делать. Арифметика с плавающей точкой подвержена ошибкам округления, и ряд операций, которые вы, например, думаете, дает, например, 6.0 может фактически дать 5.9999999999999. В этом случае любая проверка того, что значение является целым, не удастся, даже если вы, вероятно, намеревались добиться успеха. Обычно это лучший подход для сравнения float с целочисленной версией с заданной точностью, например if (x - x.to_i).abs < 0.001.

Ответ 3

TL; DR

Как правило, вы должны использовать == для сравнения чисел, когда вам не нужен цифровой тип, который должен быть в большинстве случаев. Когда вы действительно заботитесь о типе, вы должны использовать сравнение объектного равенства, унаследованное от 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 и других классах, которые позволят вам выполнять типовые разговоры и строгое сравнение сравнений. Ниже приводятся несколько примеров.

Использовать #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?

Если вы хотите создать логическое выражение без автоматических числовых преобразований, сделанных с помощью ==, вы можете использовать метод класса, унаследованный от NumeriС# zero?. Например:

(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