Конвертер систем счисления

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

Разрядность
Двоичная
Восьмеричная
Десятичная
Шестнадцатеричная
Основание
Биты — нажмите, чтобы переключить

ширина 8 бит, установлено 8

Что делает этот инструмент

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

От школьного калькулятора его отличают переключатель разрядности и сетка битов. Выберите 8, 16, 32 или 64 бита — и отрицательные числа получат своё настоящее машинное представление вместо знака минус, а каждый бит станет тем, на что можно нажать.

Что такое основание на самом деле

Основание — это сколько цифр у вас есть, прежде чем они кончатся и придётся делать перенос. У десятичной их десять, поэтому после 9 идёт 10. У двоичной их две, поэтому после 1 идёт 10. Позиция каждой цифры — это степень основания, и в этом вся суть:

1011           # число, по основанию 2
1 x 8 = 8      # бит 3
0 x 4 = 0      # бит 2
1 x 2 = 2      # бит 1
1 x 1 = 1      # бит 0
8+0+2+1 = 11   # итог, в десятичной

Основаниям выше десяти нужно больше десяти символов цифр, поэтому они занимают буквы: шестнадцатеричная идёт 0-9, затем a-f, где a — это 10, а f — 15. Так продолжается до основания 36, которое использует каждую цифру и каждую букву — наибольшее основание, записываемое обычным алфавитом, и причина, по которой этот инструмент на нём останавливается.

Почему шестнадцатеричная, а не что-то другое

Шестнадцатеричная популярна по одной конкретной причине: 16 — это 2 в четвёртой степени, поэтому ровно одна шестнадцатеричная цифра покрывает ровно четыре бита. Это превращает перевод между ней и двоичной в table lookup без арифметики — каждая цифра разворачивается в свои четыре бита независимо от соседей.

d    e    a    d
1101 1110 1010 1101   # каждая шестнадцатеричная цифра — свой ниббл

Восьмеричная работает так же с тремя битами на цифру, поскольку 8 — это 2 в третьей степени; именно поэтому права доступа в Unix восьмеричные: три бита прав на каждую группу пользователей помещаются ровно в одну цифру. У десятичной такой связи с двоичной нет, и потому перевод между ними требует настоящего деления, а не поиска по таблице.

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

Отрицательные числа и дополнительный код

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

Схема, которую использует любая современная машина, — дополнительный код: чтобы представить отрицательное число, берут его положительную форму, инвертируют каждый бит и прибавляют единицу. В результате старший бит начинает означать «отрицательное», а обычное сложение продолжает работать без особого случая для знаков.

0000 0101   # 5
1111 1010   # каждый бит инвертирован
1111 1011   # плюс один: -5 как байт, или fb в шестнадцатеричной

Расширьте регистр — и то же число получит другой рисунок: -5 это fb при 8 битах, fffb при 16 и fffffffb при 32. Значение не изменилось; изменилось число битов, которые его несут. Переключение разрядности в этом инструменте показывает именно это.

Почему 0xFF — это одновременно 255 и -1

Биты ff не сообщают, знаковые ли они. Байт, содержащий 1111 1111, читается как 255, если загружающий его код объявил беззнаковый тип, и как -1, если знаковый. Ничто в самом байте не различает эти случаи — тип это утверждение программы о битах, которые такой информации не несут.

Отсюда происходит целое семейство настоящих ошибок: контрольная сумма, которая выходит отрицательной; прочитанный из файла байт, который сравнивается как меньший нуля; C-шный char, который ведёт себя на ARM иначе, чем на x86, потому что его знаковость определяется реализацией. Всякий раз, когда знаковое и беззнаковое прочтения расходятся, инструмент показывает оба — потому что именно это расхождение вы обычно и искали.

Сетка битов

Каждый бит текущего значения показан со своим номером позиции, и нажатие переворачивает его. Системы счисления обновляются мгновенно, что делает несколько вопросов куда проще, чем вручную:

  • Какой бит выставлен в этом наборе флагов — пройдитесь по ним и прочтите позиции.
  • Какая маска нужна для битов 4 и 7 — выставьте эти два и прочтите шестнадцатеричное.
  • Что делает установка старшего бита со знаковым значением — наглядно делает его отрицательным.
  • Является ли значение степенью двойки — у степени двойки ровно один выставленный бит.

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

Большие числа остаются точными

Числа в JavaScript — это double, которые хранят целые точно лишь до 2^53, примерно до 9 квадриллионов. 64-битное значение может это превысить, и конвертер, построенный на обычных числах, тихо округлит его, выдав шестнадцатеричную строку, которая выглядит правдоподобно и неверна в последних разрядах.

Здесь всё считается на целых числах произвольной точности, поэтому полное 64-битное значение переводится точно. Режим произвольной точности идёт дальше и снимает ограничение совсем — это полезно для криптографических величин и больших идентификаторов, — но учтите: без фиксированной разрядности нет и дополнительного кода, поэтому отрицательное число в этом режиме просто несёт знак минус в каждой системе.

Частые вопросы

Почему -5 отображается как fb, а не как -101 в двоичной?
Потому что у регистра нет знака минус. Когда выбрана разрядность, отрицательные числа показываются в дополнительном коде — именно так их и хранит машина: -5 в байте это 1111 1011, то есть fb. Если нужна математическая форма со знаком, переключите разрядность на произвольную точность.
0xFF — это 255 или -1?
И то и другое: биты одинаковы, и решает только объявленный тип. Знаковое 8-битное значение читает ff как -1, беззнаковое — как 255. Когда прочтения расходятся, инструмент показывает их рядом.
Почему шестнадцатеричная используется гораздо чаще десятичной?
Потому что одна шестнадцатеричная цифра — это ровно четыре бита, поэтому она и двоичная переводятся поиском по таблице без арифметики, а цифры совпадают с границами байтов. У десятичной такой связи с двоичной нет, поэтому десятичное значение ничего не говорит о том, какие биты выставлены.
Какое здесь наибольшее основание и почему 36?
36, потому что это 10 цифр плюс 26 букв — все символы, которые даёт простой латинский алфавит. Идти выше потребовало бы соглашения о том, какие дополнительные символы использовать, а общепринятого нет.
Можно ли вставить значение с 0x или с пробелами?
Да. Префиксы 0x, 0b и 0o принимаются в соответствующем основании, а пробелы и подчёркивания игнорируются, так что можно вставлять прямо из кода или из спецификации, ничего предварительно не вычищая.
Переведётся ли 64-битное значение точно?
Да. Вся арифметика использует целые числа произвольной точности, поэтому значения выше 2^53 — там, где обычное число JavaScript начинает округлять, — остаются точными.
Отправляется ли что-нибудь из введённого на сервер?
Нет. Это арифметика в вашем браузере; ничего не загружается и не записывается в журнал, и всё работает без подключения к сети.