Алгоритм печати десятичного значения огромного (более 128 бит) двоичного числа? - PullRequest
5 голосов
/ 23 апреля 2019

TLDR, внизу:)

Краткое описание: Я нахожусь в процессе создания базовой арифметической библиотеки (сложение, вычитание, ...) для обработки больших чисел.Одна из проблем, с которыми я сталкиваюсь, - это печать этих огромных двоичных чисел в десятичное.

У меня есть огромное двоичное число, хранящееся в массиве uint64_t.например,

uint64_t a[64] = {0};

Теперь цель состоит в том, чтобы напечатать двоичное число 64 * 64 бит в консоли / файле в виде его десятичного значения.

Начальная работа: Для разработкипроблема, которую я хочу описать, как я печатал шестнадцатеричное значение.

int i;
int s = 1;
a[1] = (uint64_t)0xFF;
for(i = s; i>= 0; i--)
{
    printf("0x%08llX, ", a[i]);
}

Вывод:

0x000000FF, 0x00000000, 

Аналогично для печати значения OCT я могу просто взять 3 младших бита из [64],выведите десятичный эквивалент этих битов, сдвиньте вправо на 3 бита все биты [64] и повторяйте до тех пор, пока не будут напечатаны все значения [64].(печатать в обратном порядке, чтобы сохранить первую октябрьскую цифру справа)

Я могу напечатать шестнадцатеричное и октановое значение двоичного числа неограниченного размера, просто повторив этот алгоритм, но не смог найти / разработать для десятичногокоторый я могу повторять снова и снова, чтобы напечатать [64] (или что-то большее).

Что я подумал: Моя первоначальная идея состояла в том, чтобы продолжать вычитать

max_64 =(uint64)10000000000000000000; //(i.e.10^19)

самое большое кратное 10 внутри uint64_t, начиная с a до тех пор, пока значение внутри a не станет меньше max_64 (что в основном эквивалентно rem_64 = a%max_64), и выведите значение rem_64, используя

printf("%019llu",rem_64);

, что является первыми 19 десятичными цифрами числа a.

Затем выполните арифметическую операцию, аналогичную (не код):

a = a/max_64; /* Integer division(no fractional part) to remove right most 19 dec digits from 'a' */

, и продолжайте повторять и печатать 19 десятичных цифр.(печатать таким образом, чтобы сначала были найдены 19 цифр справа, затем следующие 19 цифр слева и т. д.).

Проблема в том, что этот процесс слишком длинный, и я не хочу использовать все это, чтобы просто напечатать значение dec.И искал процесс, который позволил бы избежать использования этих огромных, требующих много времени арифметических операций.

Я считаю, что должен быть способ печати огромных размеров, просто повторяя алгоритм (аналогично тому, как могут быть Hex и Octнапечатано), и я надеюсь, что кто-то может указать мне правильное направление.

Что может сделать моя библиотека (до сих пор):

  • Добавить (Используя Full-Сумматор)
  • Sub (с использованием полного вычитания)
  • Сравнение (путем сравнения размера массива и сравнения элементов массива)
  • Div (целочисленное деление, без дробной части)
  • Модуль (%)
  • Умножение (в основном добавление из нескольких раз :()

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

Рассмотрим проблему следующим образом: Вам дано двоичное число X из n битов (1 <= n <= 64 * 64)распечатать X в десятичном виде. Вы можете использовать существовать вg библиотека, если она абсолютно необходима, но лучше, если она не используется. </p>

TLDR: Любой алгоритм кода, ссылки или модуля, который я могу повторить для печати десятичного значения двоичного файла слишком большого и / или неизвестного размерабыло бы очень полезно.Акцент на алгоритме, т.е. мне не нужен код, если кто-то может описать процесс, я смогу его реализовать.Заранее спасибо.

1 Ответ

2 голосов
/ 23 апреля 2019

Столкнувшись с такими сомнениями и учитывая, что существует множество библиотек bigint, интересно изучить их код. Я взглянул на Java BigInteger, который имеет метод toString, и они делают две вещи:

Кнут, Дональд, Искусство компьютерного программирования , Vol. 2, Ответы на Упражнения (4.4) Вопрос 14.

...