Обход ошибок округления с помощью пола журнала в python

Чтобы найти количество цифр числа в определенной базе, я попытался написать строку:

numdigits = math.floor(math.log(num, base)) + 1

где math.log(num, base) эквивалентно math.log(num)/math.log(base)

Однако в обоих случаях это иногда приводит к неправильному количеству цифр. Это связано с тем, что ответом на math.log является число с плавающей запятой и, следовательно, имеет ограниченную точность. Например, при вычислении основания журнала 3 из 3486784401 (3^20):

>>> math.log(3486784401, 3)
19.999999999999996

Принимая во внимание это, вы получите 19, в то время как правильный ответ - 20. Я понимаю, что это из-за того, как числа с плавающей запятой представлены в двоичном формате, однако мне было интересно, есть ли способ обойти эту проблему.

Есть ли способ написать функцию, которая дает пол логарифма по любому основанию со 100% точностью?


person Yaxlat    schedule 27.07.2017    source источник
comment
Вы можете использовать sympy.log для точных вычислений.   -  person hilberts_drinking_problem    schedule 27.07.2017
comment
@YakymPirozhenko спасибо! Вы знаете, как это работает? и насколько это быстро?   -  person Yaxlat    schedule 27.07.2017


Ответы (1)


Да, есть несколько способов.

  1. Вы можете оценить количество цифр, как в своем вопросе. Затем вы можете проверить свой результат, вычислив base**result (в целых числах, чтобы получить точный результат) и посмотреть, как он сравнивается с исходным параметром. Вы корректируете result вверх или вниз на 1 и снова тестируете, пока не убедитесь, что ваш окончательный результат правильный. Вам потребуется не более 3 тестов.

  2. Точно так же вы можете пропустить тест log и просто оценивать степень base, пока она не достигнет или не превысит ваш параметр. Это сохраняет все полностью в целых числах, но требует больше времени.

  3. Конечно, есть еще один способ — сделать преобразование в нужную базу, а затем проверить количество цифр. Это, конечно, требует еще больше времени.

person Rory Daulton    schedule 27.07.2017