Предсказание вывода Python 3.6 `math.floor` для входных чисел - PullRequest
0 голосов
/ 30 августа 2018

В Python3 (я использую 3.6) они решили начать выводить интегральные значения .

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

math.floor(4.444444444444445e+85)

Выход в этом случае

44444444444444447395279681404626730521364975775215375673863470153230912354225773084672

В Python2.7 вывод был 4.444444444444445e+85.

Вопрос 1: Можно ли воспроизвести выход в 3,6? Другими словами, что это? Вычисления несколько раз на разных компьютерах дали мне один и тот же результат. Я предполагаю, что это значение зависит только от ввода 4.444444444444445e+85. Я предполагаю, что это пол двоичного представления этого числа. Факторизация объема производства составляет

2^232 × 3 × 17 × 31 × 131 × 1217 × 1933 × 13217

, где этот фактор 2 ^ 232 близок к 10 ^ 70, которые есть в научной нотации, но я не совсем уверен.

Вопрос 2: Я думаю, что я знаю, как взять число с плавающей запятой 4.444444444444445e+85, извлечь его значение и экспоненту и получить себе фактическое целое значение 4444444444444445 * 10 ** 70 или число с плавающей запятой 4.444444444444445e +85, что на мой взгляд кажется более честным значением для пола float(4.444444444444445e+85). Есть ли хороший способ восстановить это (позвольте мне это назвать) честное слово?

Хорошо, я отказываюсь называть «честным» слово десятичного представления. Поскольку компьютер хранит числа в двоичном формате, справедливо назвать честным вывод, вычисленный для двоичного представления. Это если мои предположения по Вопросу 1 верны.

1 Ответ

0 голосов
/ 30 августа 2018

Отображение вывода в шестнадцатеричном формате должно быть полезным:

>>> import math
>>> math.floor(4.444444444444445e+85)
44444444444444447395279681404626730521364975775215375673863470153230912354225773084672
>>> hex(_)
'0x16e0c6d18f4bfb0000000000000000000000000000000000000000000000000000000000'

Обратите внимание на все конечные нули! Практически на всех платформах плавающие Python представлены аппаратными средствами со значением 53, состоящими из 53 бит, и степенью степени 2. И действительно,

>>> (0x16e0c6d18f4bfb).bit_length() # the non-zero part does have 53 bits
53
>>> 0x16e0c6d18f4bfb * 2**232  # and 232 zero bits follow it
44444444444444447395279681404626730521364975775215375673863470153230912354225773084672

Итак, целое число, которое вы получили обратно, математически точно равно числу, с которого вы начали. Еще один способ увидеть это:

>>> (4.444444444444445e85).hex()
'0x1.6e0c6d18f4bfbp+284'

Если вы хотите вместо этого работать с десятичными представлениями, см. Документацию для модуля decimal.

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

float(math.floor(x))

Это воспроизведет тот же результат, который Python 2 дал для

math.floor(x)
...