Почему сравнения между очень большими значениями с плавающей точкой терпят неудачу в python? - PullRequest
0 голосов
/ 28 октября 2018

В моем понимании sys.float_info.max - это максимально возможное значение с плавающей запятой.Однако кажется, что сравнение таких больших значений не удаётся .

import math
import sys

m = sys.float_info.max                        # type 'float'

m == m                                        # True
m < m                                         # False
m > m                                         # False

m == m-1.0                                    # True
m < m-1.0                                     # False
m > m-1.0                                     # False

m == m-1e100                                  # True
m < m-1e100                                   # False
m > m-1e100                                   # False

m == m-1e300                                  # False
m > m-1e300                                   # True
m < m-1e300                                   # False

Полагаю, это из-за ограниченной точности?Если да, то в каком числовом диапазоне я могу безопасно работать?

Приведенный выше код был запущен с Python 3.5.2.

Ответы [ 2 ]

0 голосов
/ 28 октября 2018

На типичной машине, на которой запущен Python, для плавающего Python доступно 53 бита точности.Если вы попытаетесь пойти дальше, Python исключит наименьшую часть, чтобы число можно было правильно представить.

Таким образом, значение 1 поглощается или отменяется, чтобы можно было представить высокое значение, которое вы пытаетесь вычислить.

Предел получается путем вычитания (или сложения) значения, умноженного на число с плавающей точкой epsilon.

На моем компьютере:

maxfloat == 1.7976931348623157e+308
epsilon == 2.220446049250313e-16

образец тестового кода

import math
import sys

m = sys.float_info.max                        # type 'float'
eps = sys.float_info.epsilon

print(m == m-(m*(eps/10)))   # True
print(m == m-(m*eps))        # False

m*eps - это наименьшее значение, которое вы должны вычесть, чтобы сравнение не сработало.Это всегда относительно значения m.

0 голосов
/ 28 октября 2018

Может быть, если вы попытаетесь распечатать эти числа, вы лучше поймете, что они из себя представляют:

>>> sys.float_info.max
1.7976931348623157e+308
>>> sys.float_info.max - 1.0
1.7976931348623157e+308
>>> sys.float_info.max - 1e100
1.7976931348623157e+308
>>> sys.float_info.max - 1e300
1.7976931248623157e+308

Обратите внимание, что распечатка не описывает почти все проблемы, с которыми можно столкнуться с точностью чисел с плавающей запятой, но вВ этом случае «проблемы» тривиальны.Вы можете видеть, что отличается только последний номер.

...