У меня очень большое число в базе n
(n
указан пользователем), хранящийся в виде массива с каждым элементом, представляющим цифру. u[0]
- самая высокая цифра, u[1]
- вторая по величине, u[-1]
- самая низкая цифра и так далее. Ведущие нули понимаются как бессмысленные: например, если n
составляет 8, [0, 0, 0, 4, 7, 3]
эквивалентен [4, 7, 3]
и оба равны (473) в основании 8 или 315 в основании 10 или 13B
в шестнадцатеричном виде или [1, 59]
в качестве массива байтов.Преобразование очень большого базового числа n в байты
Я хочу преобразовать это в массив байтов, соответствующих представлению базового 256 того же числа с минимальными начальными нулями. У меня есть следующий код для этого:
def base_n_to_byte_array(digits, from_base):
""" Converts a base n number to a byte array.
:param digits: Digits of the number, starting from highest.
:param from_base: Base in which the number is given.
"""
x = 0
n = len(digits)
for i in range(0, len(digits)):
x += digits[i] * int(math.pow(from_base, n - i - 1))
min_length = max(math.ceil(math.log(x, 256)), 1)
byte_array = x.to_bytes(min_length, byteorder='big')
return byte_array
Это работает для меньших чисел (несколько сотен цифр). Однако выясняется, что math.pow
довольно ограничен, например, если мы используем базу 8, math.pow(8, 341)
- это самая высокая мощность, которую я могу получить, и math.pow(8,342)
с ошибкой OverflowError: math range error
.
Я знаю, что общий способ работы с большими числами - представлять их как плавающие точки, но в этом случае я использую этот код для кодирования/декодирования двоичных файлов в альтернативные представления (например, trytes). Поэтому, если из-за потери точности изменятся менее значимые байты, многие данные будут повреждены, поэтому я не могу использовать приблизительный расчет мощности - мне нужно, чтобы результат был точным.
Как я могу решить эту проблему? Есть ли версия math.pow
, которая не переполняется? Есть ли более эффективный алгоритм преобразования баз данных, который я пропускаю?
Что вам нужно [длинная арифметика] (https://en.wikipedia.org/wiki/Arbitrary-precision_arithmetic). – WhatsUp
@WhatsUp Python делает это автоматически, если вы не плаваете. – Teepeemm
@WhatsUp Я знаю, что это один из моих вариантов, я спрашиваю, как это сделать в Python3. – Superbest