Конвертер систем счисления
Переводит число между двоичной, восьмеричной, десятичной, шестнадцатеричной и любым основанием от 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 начинает округлять, — остаются точными.
- Отправляется ли что-нибудь из введённого на сервер?
- Нет. Это арифметика в вашем браузере; ничего не загружается и не записывается в журнал, и всё работает без подключения к сети.