Порядок операций вопрос в рубине

Я инициализирую экземпляр класса, который проверяет равенство двух формул.

Расчетные значения формулы фактически равны:

RubyChem::Chemical.new("SOOS").fw
=> 96.0

RubyChem::Chemical.new("OSSO").fw
= 96.0

Когда я создал новый класс для проверки равенства этих двух экземпляров, я был немного удивлен результатами:

x = RubyChem::BalanceChem.new("SOOS","OSSO")
x.balanced
=>false

y = RubyChem::BalanceChem.new("SOOS","SOOS")
y.balanced
=> true

метод инициализации RubyChem::BalanceChem находится здесь:

def initialize(formula1, formula2)
  @balanced = RubyChem::Chemical.new(formula1).fw == RubyChem::Chemical.new(formula2).fw
end

Почему ruby ​​не извлекает значения fw для формулы 1 и формулы 2 и не проверяет равенство этих значений? Каков порядок операций в Ruby и что делает Ruby? Я вижу, что мне не хватает понимания этой проблемы. Как я могу сделать эту работу? Заранее спасибо.

3 ответа

Решение

Вы, вероятно, не хотите проверять числа с плавающей запятой на равенство. Вместо этого вы должны сравнить дельты.

Попробуйте это в irb:

x = 1.000001
y = 1.0
x == y
(x-y).abs < 0.00001

Таким образом, вы найдете дельту типа 0,00001, которая, по вашему мнению, будет обрабатывать любые вариации арифметики с плавающей запятой, и использовать ее таким образом. Вы никогда не должны == поплавки.

В Ruby 1.8 есть ошибка при преобразовании чисел с плавающей точкой в ​​строку. Иногда данная строка не является хорошим представлением числа с плавающей точкой. Вот пример с 0.56:

0.5600000000000005.to_s == 0.56.to_s  #=> true
# should have returned false, since:
0.5600000000000005      == 0.56       #=> false

Это объясняет, почему два явно идентичных результата на самом деле не идентичны.

Вы, вероятно, хотите выполнить сравнение с определенным пределом погрешности, выполнить некоторое округление перед выполнением сравнения или использовать точные типы, такие как BigDecimal или же Rational,

Это, вероятно, еще одна проблема, вызванная точностью с плавающей запятой.

Я могу заверить вас, что эти значения рассчитаны до равенства.

Смотрите приоритет оператора Ruby

Другие вопросы по тегам