Escapist Marginalia

User Preferences

Interface language

Theme

radix

Radix — библиотека для перевода чисел в различные системы счисленя, написанная на TypeScript.

Обновлялось

Находившись в “поисках себя” и решив попробовать себя в программировании, наткнулся на онлайн курс CS50 Гарвардского Университета. На вводной лекции рассматривались вводные темы, основы, и одной из них было знакомство с двоичными системами счисления. Буквально за несколько миинут тему объяснили так просто и так доступно, что я действительно понял её. Это может прозвучать странно, однако в школе и даже в университете так и не смогли объяснить тему доступно. Всё сводилось к повторению определённых действия для получения результата, не более.

Во время объяснения для демонстрации использовали простенькое веб-приложение. В тот же захотелось написать нечто подобное. И только спустя время, выбрав веб-разработку как направление, у меня появилась возможность осуществить поставленную цель.

Этот проект является одним из звеньев в осуществлении давней цели, не первым и не последним, но ключевым.

История проекта#

Изначально, набравшись “теоретического минимума” знаний в веб-разработке, попытался написать именно веб-приложение. Сейчас стыдно на него смотреть, но это был этап и важно учитывать ошибки, сделанные в то время. Проблем было множество, следует выделить следующие:

  • смешение логики перевода чисел со слоем интерфейса;
  • отсутствие тестов;
  • недоступные элементы форм;
  • отсутствиие семантики в вёрстке.

Всё вместе это привело к невозможности поддерживать проект.

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

Общая информация#

radix представляет собой библиотеку, написанную на TypeScript для перевода чисел из одной системы счисления в другую.

Из преимуществ проекта:

  • Иммутабельность;
  • Отсутствие зависимостей;
  • Простой “цепной” интерфейс;
  • Типизация;
  • Малый размер (около 1.2 кб).

Обоснование и постановка цели#

Возникает вопрос, зачем вообще может понадобиться отдельный пакет для перевода систем счисления, если в языке уже присутствует функция .parseInt(string, radix), способная делать то же самое?

Дело в том, что вышеупомянутый метод имеет ряд ограничений:

  • Возвращаемое значение может быть лишь в десятичной системе счисления;
  • На вход принимаются основания систем от 2 до 36 включительно;
  • В среде JavaScript целые числа (не являющиеся на самом деле целыми) имеют безопасную границу в 253 - 1;

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

Решение ограничения значений основания системы#

.parseInt() поддерживает лишь основания от 2 до 36 включительно в первую очередь из-за простоты отображения результата, так как для систем основания от 11 и выше используются буквы латинского алфавита. Итого, имеется возможность использовать лишь основания до 36 включительно - 10 цифр + 26 букв. Какие символы использовать дальше? Трудно предложить что-то разумное.

Использовать числа вместо букв - непрактично; допустим, имеется число 11616. Какие разряды оно имеет? 1 и 16? 11 и 6? Для решения проблемы было решено использовать массив со значениями разряда: 11616 становится [ 11, 6 ]. Таким образом добиваемся однозначной репрезентации числа; пропадает необходимость использовать другие символы. В случае необходимости использования других символов, тех же латинских букв, пользователь может преобразовать их на выходе.

Безопасная граница#

В JavaScript, как известно, отсутствуют целые числа. Все числа - числа с плавающей запятой, “целые” числа имеют безопасную границу значений до [253 - 1]. Несмотря на хранение числа в виде массива разрядов, превысив границу во время перевода систем счисления, рискуем получить неверный результат. Для решения этой проблемы было решено использовать относительно новый тип данных - BigInt, позволяющее хранить целые числа произвольного размера. В силу более низкой производительности относительно обычных чисел и в особенности отсутствия сводимости с обыкновенными числами, было решено использовать BigInt лишь для изнутри перевода числа между системами.

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

Использование проекта#

Проект используется в статье про Системы Счисления; в статье описываются принципы работы систем счисления и приводятся интерактивные демонстрации принципов, а так же тренажёр для перевода систем. Благодаря разделению ответственности, удалётся использовать библиотеку в разных проектах. Одним из подобных проектов является конвертер систем счисления. На данный момент он находится в замороженном состоянии, однако уже в скором времени планируется серьёзное обновление и добавление документации на отдельную страницу.