Если вы не вычисляете свои числа с плавающей точкой в одном и том же месте или с точно таким же уравнением, то у вас могут быть ложные отрицания с этим кодом (из-за ошибок округления). Например:
>>> 0.1 + 0.2 in [0.6/2, 0.3] # We may want this to be True
False
В этом случае у нас может быть просто пользовательская функция "in
", которая фактически сделает это истинным (в этом случае может быть лучше / быстрее использовать numpy.isclose
вместо numpy.allclose
):
import numpy as np
def close_to_any(a, floats, **kwargs):
return np.any(np.isclose(a, floats, **kwargs))
В документации есть важное примечание:
Внимание
Значение по умолчанию atol
не подходит для сравнения чисел, которые намного меньше единицы (см. Примечания).
[...]
если ожидаемые значения значительно меньше единицы, это может привести к ложным срабатываниям.
В примечании добавлено, что atol
не равно нулю, в отличие от math.isclose
* abs_tol
. Если вам нужен пользовательский допуск при использовании close_to_any
, используйте kwargs
, чтобы передать rtol
и / или atol
до значения numpy. В конце концов, ваш существующий код будет выглядеть так:
if close_to_any(myFloatNumber, myListOfFloats):
print('Found it!')
else:
print('Sorry, no luck.')
Или у вас может быть несколько вариантов close_to_any(myFloatNumber, myListOfFloats, atol=1e-12)
, обратите внимание, что 1e-12
является произвольным, и вы не должны использовать это значение, если у вас нет веских причин для этого.
Возвращаясь к ошибке округления, которую мы наблюдали в первом примере, это даст:
>>> close_to_any(0.1 + 0.2, [0.6/2, 0.3])
True