равенство с плавающей точкой в ​​Python и вообще

У меня есть фрагмент кода, который ведет себя по-разному в зависимости от того, просматриваю ли я словарь для получения коэффициентов преобразования или использую ли я их напрямую.

Следующий фрагмент кода напечатает1.0 == 1.0 -> False

Но если вы заменитеfactors[units_from] с10.0 а такжеfactors[units_to ] с1.0 / 2.54 это напечатает1.0 == 1.0 -> True

#!/usr/bin/env python

base = 'cm'
factors = {
    'cm'        : 1.0,
    'mm'        : 10.0,
    'm'         : 0.01,
    'km'        : 1.0e-5,
    'in'        : 1.0 / 2.54,
    'ft'        : 1.0 / 2.54 / 12.0,
    'yd'        : 1.0 / 2.54 / 12.0 / 3.0,
    'mile'      : 1.0 / 2.54 / 12.0 / 5280,
    'lightyear' : 1.0 / 2.54 / 12.0 / 5280 / 5.87849981e12,
}

# convert 25.4 mm to inches
val = 25.4
units_from = 'mm'
units_to = 'in'

base_value = val / factors[units_from]
ret = base_value * factors[units_to  ]
print ret, '==', 1.0, '->', ret == 1.0

Позвольте мне сначала сказать, что я почти уверен, что здесь происходит. Я видел это раньше в C, просто никогда в Python, но после того, как Python реализован в C, мы видим это.

Я знаю, что числа с плавающей запятой изменят значения, идущие от регистра ЦП к кешу и обратно. Я знаю, что сравнение двух одинаковых переменных вернет false, если одна из них была выгружена, а другая осталась в регистре.

Вопросы

Каков наилучший способ избежать подобных проблем? ... В Python или вообще.Я делаю что-то совершенно не так?

Примечание

Это, очевидно, часть урезанного примера, но я пытаюсь сделать это с классами длины, объема и т. Д., Которые можно сравнивать с другими объектами того же класса, но с разными единицами.

Риторические Вопросы

Если это потенциально опасная проблема, так как она заставляет программы вести себя недетерминированно, должны ли компиляторы предупреждать или сообщать об ошибке, когда обнаруживают, что вы проверяете равенство чисел с плавающей точкойДолжны ли компиляторы поддерживать опцию для замены всех проверок равенства с плавающей запятой на «достаточно близкую» функцию?Компиляторы уже делают это, и я просто не могу найти информацию.

Ответы на вопрос(8)

Ваш ответ на вопрос