Реализация библиотеки с плавающей запятой любой точности - PullRequest
1 голос
/ 02 апреля 2019

Я должен реализовать библиотеку с плавающей запятой любой точности, поэтому показатель степени и мантисса должны быть бесконечно положительным целым числом. Позже мне придется создавать функции сложения, вычитания и т. Д., Используя возможности процессора x86. Я должен использовать C ++ / C (я могу использовать ассемблерные вставки), и я могу использовать готовые библиотеки.

В начале у меня проблемы: 1. какой тип используется для хранения бесконечно большого натурального числа? 2. какие библиотеки / функции позволят мне использовать возможности процессора и будут работать с указанным выше типом данных?

Ответы [ 2 ]

3 голосов
/ 02 апреля 2019
  1. Какой тип используется для хранения бесконечно большого натурального числа?

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

Вы можете обернуть вектор в пользовательский тип в C ++, чтобы обеспечить объектно-ориентированный интерфейс.

2. Какие библиотеки / функции позволят мне использовать возможности процессора и будут работать с указанным выше типом данных?

Если вы создадите пользовательский тип, другие библиотеки не будут иметь прямой поддержкидля этого.Универсальные библиотеки шаблонов могут, однако, использоваться, если ваш класс предоставляет совместимый интерфейс.

Например, если вы предоставляете оператор сравнения и оператор присваивания, тогда не должно возникнуть проблем при сортировке объектов пользовательского класса с использованием std::sort изстандартная библиотека.

Я могу использовать готовые библиотеки.

Обычно это хорошая идея.Я рекомендую это.

0 голосов
/ 02 апреля 2019

Одним из важных соображений является то, какую базу вы будете использовать для представления своих внутренних единиц.Как уже говорили другие, это, вероятно, будет вектор отдельных единиц, которые вы затем обработаете, используя те «бумажные» операции, которые вы изучили в начальной школе.Возможно структура, которая содержит отдельные векторы для mantassa и показателя степени и флаг для знака каждого из них.Но что происходит в этих отдельных единицах?

Этот выбор зависит от эффективности этих операций.

Вы можете решить, что использовать символы и основание 10 - это самый простой способ кодировать это, иФункции чтения и записи очень тривиальны!Но на самом деле процессор довольно неэффективен при обработке одного байта за раз в десятичном формате.Это отлично подходит для чтения чисел, хотя!Например, выполнение 56 * 37 потребует следующих операций над «десятичной» архитектурой:

  • 6 * 7 -> 42
  • 42/10 -> ________ 4
  • 42% 10 -> ___________ 2 *
  • 5 * 7 -> 35
  • 35/10 -> ______ 3
  • 35% 10 -> ________ 5
  • 6 * 3 -> 18
  • 18/10 -> ______ 1
  • 18% 10 -> ________ 8
  • 5 * 3 -> 15
  • 15/10 -> ____ 1
  • 15% 10 -> ______ 5
  • 4 + 5 + 8 -> 17
  • 17/10 -> ______ 1
  • 17% 10 -> ________ 7 *
  • 3 + 1 + 5 + 1 -> 10
  • 10/10 -> ____ 1
  • 10% 10 -> ______ 0 *
  • 1 + 1 -> 2
  • 2/10 -> 0
  • 2% 2 -> ____ 2 *
  • Окончательный ответ __ 2 0 7 2

Это много операций умножения и деления, и это только 2 цифры!

Вы можете решить, что используйте весь байт 0-255 намного эффективнее, а базовая математика 256 намного проще.Это так, тем более что деление цифр / 10 и% 10 шагов становятся простыми сдвигами и масками!Но чтение и запись чисел произвольной длины в десятичном виде и вне их намного, намного сложнее и делает их еще более трудными, если вы решите использовать показатель степени 2!

Выполнение тех же математических операций в базе 65536более эффективен, а база 4G на 64-битном процессоре еще более эффективна для математики и не намного сложнее для печати.С ассемблером вы даже можете использовать 64-битное хранилище и 128-битные операции умножения!

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

Один хитрый способ повысить эффективность печати и обеспечить достаточную эффективность математики - это фактически сохранить число цифр в двоичном виде в каждой единице хранения.32-разрядное хранилище может фактически содержать целое число длиной до 9 цифр в каждой единице.Выполняя математику с начальным 1 миллиардом, вам нужно будет выполнять все дополнительные операции разделения цифр, как показано выше, каждые 9 цифр!

Считывание строки чисел включает считывание 9 цифр за раз в хранилище, а затем исправлениепоказатель экспоненты, который я рекомендую, все еще имеет степень 10. Числа всегда должны храниться внутри в нормализованном формате с плавающей запятой, где только одна цифра (или, возможно, всегда 0) выше десятичной точки.Если входная строка содержит десятичную точку в другом месте или на самом деле является целочисленным значением, то вы можете исправить это, поиграв с показателем экспоненты.Числа всегда печатаются в этом формате или в виде целых чисел.Таким образом, неиспользуемые цифры номера всегда находятся внизу наименее значимой единицы, и если они равны нулю, то они полностью функциональны.

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

Считать само значение показателя в вектор удержания сложно, но, возможно, вы можете жить с показателем, ограниченным 64-битным диапазоном, что означает, что вам не нужно выполнять многобайтовую манипуляцию с самим номером экспоненты? Это позволяет числам до 0.99E10sextillion (это 19-значное число только для показателя степени), что должно быть достаточно для большинства целей. Это предполагает, что показатель степени все еще представляет степень 10, что делает хранение значений удобным, или вы могли бы сделать это в степенях в миллиарды, увеличив диапазон «экспоненциально», но тогда чтение числа текста становится более трудным, так как чтение числа должны быть выровнены (аналогично операции предварительного выравнивания сложения / вычитания), но вы также извлекаете выгоду из того, что не нужно делать это сложение / вычитание предварительного выравнивания.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...