Проверка того, что float по модулю int является конечным порядковым числом - PullRequest
2 голосов
/ 01 июня 2011

В цикле for я интегрирую по времени с постоянным дробным шагом по времени, dt. Я хочу сохранить результаты моделирования только для целых (конечных порядковых) временных точек. Мое решение заключается в следующем,

dt = 0.1
steps = 100

for step in range(steps):
    if (step*dt) % 1 == 0.0:
        print step

Я никогда не доверял модульной арифметике на числах с плавающей точкой. Есть ли лучший способ проверить, является ли число с плавающей точкой неотъемлемым или я просто параноик?

Ответы [ 2 ]

2 голосов
/ 01 июня 2011

Это опасно на любом языке программирования. В вашем примере, 0.1 не может быть точно представлен в виде с плавающей точкой, так что тест никогда не пройдет (ну, я полагаю, он может пройти после 2 ^ 24 итераций или около того) .Во многих случаях размер шага может не иметь точного представления в плавающей точке, так что накопленная ошибка округления приводит к тому, что тест по ошибке запускает / не запускает.В других случаях, когда накопленное значение увеличивается, со временем оно начнет терять точность из-за увеличения показателя степени (в вашем примере, если Python по умолчанию использует одинарную точность, вы получите ошибочный триггер после 20971529 итераций).

Попробуйте найти способ избежать выполнения тестов на равенство для значений с плавающей запятой (проверка на интегральные значения является одним из таких тестов).Так что в вашем случае просто протестируйте на step % 10.

1 голос
/ 01 июня 2011

Я тоже не доверяю числам с плавающей запятой, вы можете использовать Десятичный тип или вы можете использовать types . Мне нравятся типы лучше.

...