2016-03-17 1 views

ответ

0

Поскольку 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

+1

«Если вы используете число, которое может быть представлено именно для' v2' (например, 'v2 = 1,0/(2 ** 20)') результатом запуска программы будет 0. " - нет, результат все равно около 0,95, как и должно быть, поскольку мы не вычитаем миллион кратных v2. Кроме того, точная представимость значения, используемого для v2, недостаточна; нам также нужна точность промежуточных сумм, чтобы гарантировать точно правильный конечный результат. Например, использование 'v2 = 1000.0/2 ** 30' все еще вызывает ошибку округления в промежуточных значениях, несмотря на то, что начальное значение не было окружено. – user2357112

+1

Действительно, вам понадобится число, которое точно выражается с 1 + 3 мантиссами. 1000 = бинарный (1111101000) требуется 1 + 6 бит мантиссы. – LutzL

+0

@ user2357112, спасибо за исправление. Действительно, я не учитывал потерю точности и тот факт, что число итераций должно быть изменено. Я уточню ответ, чтобы быть более точным. – kostya

0

Давайте посмотрим, что 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