Меньше или равно оператору для числа с плавающей точкой? - PullRequest
0 голосов
/ 02 мая 2019

Я понимаю, что функцию np.islcose () можно использовать для безопасной проверки чисел с плавающей запятой на равенство.Что меня сейчас смущает, так это то, что я получаю различные результаты от использования стандартного оператора <=.Например: </p>

add_to = 0.05
value64 = np.float64(0.3) + add_to*4
value32 = np.float32(0.3) + add_to*4
threshold = 0.5
print('is close?')
print(np.isclose(value64, threshold))
print(np.isclose(value32, threshold))
print('is less than or equals to?')
print(value64 <= threshold)
print(value32 <= threshold)

Дает мне

is close?
True
True
is less than or equals to?
True
False

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

Заранее спасибо за любую помощь!

Ответы [ 2 ]

1 голос
/ 02 мая 2019

Согласно этой разнице между Python float и numpy float32 , есть разница между тем, как python видит np.float32 и np.float64.Если вы действительно проверите промежуточные значения value64 и value32, вы увидите:

value32 = 0.5000000119209289
value64 = 0.5

, что объясняет, почему print(value32 <= threshold) оценивается как ложное.Из-за двоичных ошибок я сомневаюсь, что округление до восьмого десятичного знака будет безопасным, так как с value32 у вас будет 0.50000001.

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

np.float64(0.1) + np.float64(0.2)

, поскольку это оценивается как 0.30000000000000004, и поэтому у вас могут возникнуть ошибки при использовании >= или <=.Эта ошибка также возникает, если вы используете библиотеку decimal.Короче говоря, есть некоторые цифры, от которых невозможно избежать какой-либо ошибки.Единственный известный мне способ обойти это - округлить.

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

Если вы беспокоитесь о произвольной природе того, куда округлятьчисло до, я бы искал строку длиной 0 больше 4 после значащей цифры, а затем обрезал ее там.

0 голосов
/ 02 мая 2019

Вы можете определить функции, которые объединяют < и > с isclose.

def approx_lte(x, y):
    return x <= y or np.isclose(x, y)
def approx_gte(x, y):
    return x => y or np.isclose(x, y)

Они аналогичны <= и >=, за исключением того, что они также используют np.isclose() для проверки на равенство.

...