При портировании кода с Python 2 на Python 3 тесты подсвечивали числовую регрессию при вычислении дат с datetime.datetime
, что мне трудно объяснить.Небольшое отклонение между вычислениями datetime.datetime в Python 2 и 3
Как воспроизвести
date_max = datetime.datetime(2016, 9, 28, 4, 21, 5, 228000)
date_min = datetime.datetime(2016, 9, 28, 4, 21, 4, 460315)
date_futur = date_min + datetime.timedelta(seconds=((date_max - date_min).total_seconds()/2))
Выходы
Выход из print date_futur
в Python 2.7.12:
2016-09-28 04:21:04.844158
Выход из print(date_futur)
в Python 3.5.2:
2016-09-28 04:21:04.844157
Выпуск
Это только одна разница микросекунды, но это ошибки мне, потому что я не могу это объяснить, так что я не знаю, смогу ли я обновить мои результаты испытаний с новым поведением Python 3, или если что-то более сложное под рукой.
Возможно привести
Может быть, это из-за того, как Python 3 округляет 0,5 до ближайшего четного числа, а не вверх, как Python 2?
Update
Результат (date_max - date_min).total_seconds()/2
в обоих случаях составляет 0.8441575 секунд. Однако после того, как передал datetime.timedelta
конструктор:
Python 2:
datetime.timedelta(0, 0, 383843)
Python 3:
datetime.timedelta(0, 0, 383842)
Так что-то шаткий происходит в timedelta
конструктор!
Я попытался заменить его на '/ 2.0', Python 2 не изменил его поведения. Может быть, если вы передадите float в timedelta, он применит к нему функцию «round», которая может объяснить различное поведение? –
Я думаю, что это может быть на самом деле, если вы делаете расчет «вручную», '(date_max - date_min) .total_seconds()/2' дает 844157 **. 5 ** микросекунды ... Это выглядит подозрительно? –
@ValentinB. Он преобразует его в 'int', используя float-версию' mod': if 'isinstance (seconds, float): secondsfrac, seconds = _math.modf (seconds) assert seconds == int (seconds) seconds = int (секунд) secondsfrac + = daysecondsfrac assert abs (secondsfrac) <= 2.0' – DeepSpace