Вопрос

Я наткнулся на очень странную ошибку.Прочитайте комментарии в коде, чтобы узнать, в чем именно заключается ошибка, но по сути переменная по модулю 1 возвращает 1 (но она не равна 1!).Я предполагаю, что существует проблема с отображением, когда значение float чрезвычайно близко к единице, но не точно.Однако он должен быть равен нулю по модулю.Я не могу легко протестировать этот случай, потому что (last % 1) != 1.0 !Когда я пытаюсь подключить те же числа к другому терминалу python, все работает правильно.Что происходит?

def r(k,i,p):
    first = i*p
    last = first + p

    steps = int((i+1)*p) - int(i*p)
    if steps < 1:
        return p
    elif steps >= 1:
        if k == 0:
            return 1 - (first % 1)
        elif k == steps:
            if i == 189:
                print last, 1, type(last), last % 1, last - int(last)
                # Prints: 73.0 1 <type 'float'> 1.0 1.0
                print last % 1 == 1 # Returns False
            if last % 1 == 1.0:
                return 0
            return (last % 1)
        else:
            return 1
Это было полезно?

Решение

Добро пожаловать в IEEE754, приятного вам пребывания.

Другие советы

Печать не показывает полную точность сохраненного числа, вы можете использовать repr() чтобы сделать это

>>> last=72.99999999999999
>>> print last, 1, type(last), last % 1, last - int(last)
73.0 1 <type 'float'> 1.0 1.0
>>> print last % 1 == 1
False
>>> print repr(last), 1, type(last), repr(last%1), repr(last - int(last))
72.999999999999986 1 <type 'float'> 0.99999999999998579 0.99999999999998579
>>> 

Вам следует использовать math.fmod(x, y).Вот выдержка из http://docs.python.org/library/math.html:

"Обратите внимание, что выражение Python x % y может не возвращать тот же результат.Цель стандарта C состоит в том, чтобы fmod(x, y) был точно (математически;с бесконечной точностью), равной x - n * y для некоторого целого числа n, такого, что результат имеет тот же знак, что и x, и величину, меньшую, чем abs (y).X % y в Python вместо этого возвращает результат со знаком y и может быть не совсем вычислимым для аргументов с плавающей точкой.Например, fmod(-1e-100, 1e100) равен -1e-100, но результатом Python -1e-100 % 1e100 является 1e100-1e-100, который не может быть представлен точно как значение с плавающей точкой, и раунды к удивительному 1e100.По этой причине функция fmod() обычно предпочтительнее при работе с числами с плавающей запятой, в то время как x % y в Python предпочтительнее при работе с целыми числами ".

Вы могли бы попробовать математика.fmod функция вместо last % 1, может быть, это лучше подходит для вашей проблемы.Или вы могли бы переформулировать свою проблему в целочисленном пространстве.

В любом случае, не рекомендуется сравнивать значения с плавающей запятой, используя равенство == оператор, из-за неточных результатов даже от кажущихся тривиальными операций, таких как 0.1 + 0.2 == 0.3

Если вам нужна произвольная точность, есть несколько проектов, которые делают именно это. неуклюжий обрабатывает целые числа с высокой точностью, мпмат который выглядит довольно неплохо и большое плавание который обертывает MPFR.Того, что у вас есть, может быть достаточно из ответа gnibbler, но, на всякий случай.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top