Ошибка чисел Python: большое число добавить небольшое число
Это упражнение из курса глубокого обучения Udacity.
Может кто-нибудь объяснить, почему окончательный ответ не 1,0?
v1 = 1e9
v2 = 1e-6
for i in range(int(1e6)):
v1 = v1 + v2
print 'answer is', v1 - 1e9
# answer is 0.953674316406
2 ответа
Так как 1e-6
не может быть представлен точно как значение с плавающей запятой:
print("{:.75f}".format(1e-6))
'0.000000999999999999999954748111825886258685613938723690807819366455078125000'
Если вы используете число, которое может быть представлено именно так, как v2 = 1.0/(2**20)
и измените счетчик итераций на 2**20
ты получишь 0
, Однако, как указал @user2357112, даже это свойство сохраняется, только если все промежуточные результаты могут быть представлены точно с использованием значения с плавающей запятой.
Обратитесь к руководству по Python для получения более подробной информации: https://docs.python.org/3/tutorial/floatingpoint.html
Давай проверим что v1
видит v2
в сложении с плавающей точкой:
>>> v3 = (v1+v2)-v1
>>> print "%.25f %.25f" % (v3,1e6*v3)
0.0000009536743164062500000 0.9536743164062500000000000
Что происходит, так это то, что все, кроме ведущих 1
вывести из двоичной мантиссы 1e-6
при выравнивании показателя степени с 1e9
, Это означает, что окончательное значение 10**6 * 2**(-20) = (1.024)**(-2)
, что дает именно наблюдаемое значение
>>> print "%.17f" % (1.024)**(-2)
0.95367431640625000