Преобразование больших шестнадцатеричных чисел в десятичные числа

У меня есть большое шестнадцатеричное число, например CD4A0619FB0907BC00000 (25!) или любое другое подобное число. Теперь, используя только стандартный код C/C++ (без таких библиотек, как Boost), я хочу преобразовать это число в десятичное число 15511210043330985984000000. К сожалению, оно слишком велико для 64-битного целого числа (например, long long), и я не хочу использовать любые типы данных с плавающей запятой. Если это вообще возможно, то как вы можете это сделать?


person sigalor    schedule 24.07.2015    source источник
comment
Это возможно, но вы будете переписывать код, уже написанный библиотеками.   -  person NathanOliver    schedule 24.07.2015
comment
@NathanOliver На самом деле я не хочу переписывать код, я просто хочу понять, как это делается.   -  person sigalor    schedule 24.07.2015
comment
Вам нужно одно или оба: преобразование из базы во внутреннее представление и/или преобразование в базу из внутреннего представления. Если ваше внутреннее представление представляет собой какой-либо плотный двоичный файл, то преобразование из шестнадцатеричного во внутреннее тривиально (не требует общего метода). Если ваше внутреннее представление представляет собой десятичную строку, преобразование из внутреннего в десятичное не требуется. Общее из базового преобразования просто слева направо, умножьте частичный результат, затем добавьте следующую цифру. Общее для основания - это деление справа налево и использование остатка в качестве выходной цифры.   -  person JSF    schedule 24.07.2015
comment
типы с плавающей запятой не являются решением для этого, поскольку их точность ограничена   -  person phuclv    schedule 06.09.2016


Ответы (2)


Предполагая, что вы не хотите использовать какие-либо ресурсы, которые могут соответствовать вашему описанию «библиотеки, такие как Boost». Простой ответ состоит в том, чтобы написать собственное подмножество из одного только с теми операциями, которые вам нужны. Если 32 шестнадцатеричных цифры достаточно, то проще всего было бы создать собственное 128-битное целое число без знака и закодировать функцию деления на 10 (производя частное и остаток) для этого 128-битного целого числа. Вам действительно не нужны никакие другие функции, а разделить на 10 довольно просто. Преобразование до 32 шестнадцатеричных цифр в 128-битные целые тривиально, а генерация десятичного вывода из серии деления на десять тривиальна. Если вам нужен практически неограниченный размер, то, вероятно, проще представить десятичное число в виде строки цифр и написать процедуру, умножающую ее на 16 и добавляющую еще одну цифру. Это никогда не было бы эффективным решением, скорее всего, его было бы проще кодировать для ваших целей и неограниченного размера.

person JSF    schedule 24.07.2015
comment
Спасибо, статическое деление на 10 функций было решением. В итоге я умножил число (внутренне представленное массивом битов) на 205 и выполнил битовый сдвиг на 11 вправо, потому что 205/2048 почти равно 1/10. - person sigalor; 24.07.2015
comment
Я не верю, что 205/2048 — достаточно хорошее приближение 1/10 для ваших целей. Если вы представляете двоичное число как серию фрагментов, меньших (не равных по размеру), чем максимальный размер, для которого у вас есть собственное деление, деление на 10 довольно просто. Установите аккумулятор на ноль, затем для каждого фрагмента (от самого высокого порядка к самому низкому порядку) сдвиньте аккумулятор влево на размер фрагмента, добавьте фрагмент, установив эту позицию частного на частное и установив аккумулятор на остаток (этого родного разделение). - person JSF; 24.07.2015

Если вы не хотите использовать внешние библиотеки, вам придется самостоятельно реализовать целочисленный тип произвольной точности. См. этот вопрос, чтобы узнать, как это сделать. . Вам также понадобится функция/конструктор для преобразования шестнадцатеричных строк в новый тип. См. этот вопрос, чтобы узнать, как это сделать.

person Daniel    schedule 24.07.2015