Конвертер систем счисления
Переводит число между двоичной, восьмеричной, десятичной, шестнадцатеричной и любым основанием от 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-битное значение переводится точно. Режим произвольной точности идёт дальше и снимает ограничение совсем — это полезно для криптографических величин и больших идентификаторов, — но учтите: без фиксированной разрядности нет и дополнительного кода, поэтому отрицательное число в этом режиме просто несёт знак минус в каждой системе.
Из двоичной в десятичную и из десятичной в двоичную
Двоичная и десятичная — единственная пара здесь, у которой нет ничего общего: два не степень десяти, а десять не степень двух, поэтому ни одно направление не сводится к поиску по таблице и оба требуют настоящей арифметики. И это к тому же не одна и та же арифметика — быстрый способ вручную в одну сторону не является обращением быстрого способа обратно.
- Из двоичной в десятичную, удвоением: начните с нуля на самом левом бите, а затем для каждого бита удваивайте накопленное и прибавляйте этот бит. Для 1011 это даёт 1, 2, 5, 11 — один проход, никаких весов разрядов запоминать не нужно, и именно так этот инструмент читает то, что вы вводите.
- Из двоичной в десятичную, по позициям: сложите вес каждого выставленного бита — это разобранный пример выше. Быстрее, когда выставлены два-три бита, и медленнее, когда выставлено большинство.
- Из десятичной в двоичную, делением: делите на два и записывайте остаток, снова и снова, пока ничего не останется, — а затем читайте остатки снизу вверх. Ответ приходит младшим битом вперёд, поэтому всё время, пока вы его пишете, он выглядит перевёрнутым.
- Из десятичной в двоичную, вычитанием: отнимайте наибольшую степень двойки, которая помещается, и повторяйте. 200 теряет 128, остаётся 72; 72 теряет 64, остаётся 8; 8 теряет 8, не остаётся ничего — значит, выставлены биты 7, 6 и 3, а байт равен 1100 1000. Быстрее деления всякий раз, когда выставленных битов мало.
Одного не покрывает здесь ни один ручной способ: у отрицательного десятичного числа вообще нет двоичной формы, пока не выбрана разрядность. Спросите «минус пять в двоичной» — и честным ответом будет вопрос: сколько битов? Это и решает переключатель разрядности, и об этом раздел о дополнительном коде выше. В режиме произвольной точности разрядности нет, поэтому знак минус просто переходит вместе с числом в любую систему счисления.
Из десятичной в шестнадцатеричную и обратно
Почти никто из тех, кто делает это часто, не делит на шестнадцать. Связь шестнадцатеричной с двоичной и есть короткий путь: переведите десятичное число в двоичное один раз, разрежьте биты на группы по четыре справа и прочтите каждую группу как одну шестнадцатеричную цифру. Обратно — тот же маршрут наоборот: разверните каждую цифру в её четыре бита и сложите веса выставленных. Для всего, что помещается в байт, есть путь ещё короче: первая шестнадцатеричная цифра весит шестнадцать вторых, так что умножьте и сложите.
- 255 — это ff: байт, в котором выставлены все биты. Его и стоит знать наизусть, потому что на нём байт кончается.
- 256 — это 100. На шаг дальше полного байта цифры перекатываются ровно так же, как 99 перекатывается в 100 в десятичной, и шестнадцатеричное число получает разряд, который байт вместить не может.
- 65535 — это ffff, а 65536 — это 10000: те же два ориентира байтом выше, там, где кончается шестнадцатибитный счётчик.
- 4096 — это 1000, и поэтому размеры страниц, выравнивания и смещения в памяти выглядят круглыми в шестнадцатеричной и рваными в десятичной. Шестнадцатеричная считает четвёрками битов, и железо тоже.
Заглавные и строчные буквы значения не имеют: FF и ff — одно и то же значение, инструмент принимает на входе оба написания и печатает на выходе строчные. Чего он делать не станет — так это гадать. Префикс 0x принадлежит шестнадцатеричному полю и в десятичном отвергается, а не отбрасывается молча: значение, прочитанное не в том основании, — единственная ошибка, которую конвертер не имеет права сделать правдоподобной.
Из восьмеричной в десятичную и ведущий ноль, который меняет ответ
Восьмеричная держится в одном месте прочнее, чем во всех прочих: права доступа к файлам, где три бита прав на каждую группу пользователей помещаются ровно в одну восьмеричную цифру. Перевод в десятичную — это обычная позиционная арифметика со степенями восьмёрки: 755 в восьмеричной это семь шестьдесят четвёрок плюс пять восьмёрок плюс пять, то есть 493. Обратное направление — деление на восемь с остатками, читаемыми снизу вверх, той же формы, что и из десятичной в двоичную, и по той же причине: у восьмёрки тоже нет связи с десяткой.
- 755 — это 493 в десятичной, 644 — это 420, а 777 — это 511. Ни одно из этих десятичных чисел никому не нужно, и в этом всё дело: права записывают в восьмеричной потому, что цифры совпадают с битами прав, а не потому, что значение что-то считает.
- Ведущий ноль — это признак основания в C и в Python 2: 0755 там восьмеричное, то есть число 493. Python 3 отвергает такую запись вовсе и требует 0o755, чем убрал целое семейство тихих ошибок.
- YAML 1.1 тоже читает незакавыченное 0755 как 493 — поэтому режим прав в файле конфигурации приходится брать в кавычки, иначе он перестаёт быть тем режимом, который вы написали.
- JSON не разрешал этого никогда: его грамматика запрещает ведущий ноль в числе, поэтому 0755 там вообще не число, а ошибка разбора — самое громкое из трёх поведений и единственное, которое нельзя прочесть неправильно.
Этот инструмент не видит в ведущем нуле признака чего бы то ни было. Основание задаёт поле, в которое вы вводите: 0755 в десятичном поле — это 755, а в восьмеричном — 493; префикс 0o принимается в восьмеричном поле и отвергается везде ещё. Угадывать основание по префиксу означало бы возвращать не то число, которое ввели.
Из восьмеричной в шестнадцатеричную: пара без короткого пути
Обе — степени двойки, поэтому обе представляют собой чистую перегруппировку тех же самых битов, и всё же это единственная пара из четырёх систем, где нет никакого правила «цифра в цифру». Одна восьмеричная цифра — это три бита, одна шестнадцатеричная — четыре, и ни одно из этих чисел не делится на другое, поэтому границы никогда не совпадают. Обойти запись битов и их перегруппировку нельзя.
- Запишите каждую восьмеричную цифру её тремя битами по порядку: 755 превращается в 111 101 101.
- Перегруппируйте эти биты по четыре с правого конца, дополняя слева нулями, когда счёт не делится ровно: 0001 1110 1101.
- Прочтите каждую четвёрку как одну шестнадцатеричную цифру: 1ed. Дополнение не с того конца — классическая здешняя ошибка, и она не выглядит ошибкой: она просто молча умножает ответ.
То, что две шестнадцатеричные цифры — это ровно один байт, а две восьмеричные — нет, и есть вся причина, по которой шестнадцатеричная вытеснила восьмеричную при чтении памяти: восемь битов — это две восьмеричные цифры и две трети, поэтому граница байта попадает в середину цифры. Восьмеричная подходила машинам, у которых размер слова был кратен трём битам; шестнадцатеричная подходит восьмибитному байту. А на этой странице сетка битов для этой пары быстрее любого ручного способа — выставьте биты один раз, и оба поля уже показывают ответ.
Частые вопросы
- Почему -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 начинает округлять, — остаются точными.
- Отправляется ли что-нибудь из введённого на сервер?
- Нет. Это арифметика в вашем браузере; ничего не загружается и не записывается в журнал, и всё работает без подключения к сети.
- Как перевести двоичное число в десятичное вручную?
- Удваивайте и прибавляйте, слева направо: начните с нуля и для каждого бита удвойте накопленное и прибавьте бит. 1011 даёт 1, потом 2, потом 5, потом 11. Это один проход, и веса разрядов запоминать не нужно; тот же способ работает в любом основании — умножайте на основание вместо удвоения.
- Сколько будет 255 в шестнадцатеричной и почему это число попадается постоянно?
- ff. Это байт со всеми восемью выставленными битами, то есть наибольшее значение, которое вмещает один байт, и точка, где счёт перекатывается во второй байт, — поэтому оно и встречается в цветовых каналах, масках и ограничениях размера. На единицу больше — 256, что записывается как 100.
- Одно ли это число — 0755 и 755?
- Здесь — да в десятичном поле и нет в восьмеричном: основание задаёт поле, а ведущий ноль это просто цифра ноль. В остальном всё зависит от языка: C и Python 2 читают 0755 как восьмеричное, то есть 493; Python 3 такую запись отвергает и требует 0o755; YAML 1.1 читает её как 493; JSON считает синтаксической ошибкой.
- Как перевести восьмеричное число в шестнадцатеричное?
- Через двоичное, потому что более короткого пути нет: три бита на восьмеричную цифру, четыре на шестнадцатеричную, и они никогда не совпадают. Разверните каждую восьмеричную цифру в её три бита, перегруппируйте всю цепочку по четыре начиная справа и прочтите каждую четвёрку как шестнадцатеричную цифру: 755 превращается в 111 101 101, затем в 0001 1110 1101, затем в 1ed.
Похожие инструменты
- Конвертер размеров данных
То же число, прочитанное как объём данных, а не как набор битов: там количество байтов превращается в КБ, МБ и ГБ рядом с КиБ, МиБ и ГиБ — и видно, где две системы расходятся.
- Калькулятор процентов
Основание говорит, как число записано; процент говорит, насколько оно велико рядом с другим. Там считаются доли, изменения и обратные задачи, и рядом с ответом стоит формула с вашими числами.