Чему равно −5 в 8-битном дополнительном коде?
11111011 11111011, то есть 0xFB.
Введите знаковое целое и получите прямой, обратный, дополнительный и смещённый код сразу, от 4 до 64 бит. Или вставьте битовый паттерн либо hex-байт и увидите все пять прочтений рядом. Локально и бесплатно.
Введите знаковое целое число. Все четыре представления считаются сразу — заранее знать, какое использует ваша система, не нужно.
| Кодировка | Биты | Hex |
|---|---|---|
| Прямой код | 1000 0101 | 85 |
| Обратный код | 1111 1010 | FA |
| Дополнительный код | 1111 1011 | FB |
| Смещённый код | 0111 1011 | 7B |
Прямой и обратный код тратят по одному битовому паттерну на отрицательный ноль, поэтому вмещают на одно значение меньше, чем дополнительный, и до самого отрицательного числа не дотягивают.
Вы нашли байт в дампе памяти или в регистре и не знаете, как его следует читать. Вставьте его и сразу увидите, что он означает в каждой интерпретации — какая из них верна, зависит от системы-источника, поэтому показаны все.
| Читается как | Значение |
|---|---|
| Беззнаковое | 251 |
| Прямой код | -123 |
| Обратный код | -4 |
| Дополнительный код | -5 |
| Смещённый код | 123 |
Вычислено тем же движком, который использует инструмент выше, поэтому эти значения не могут с ним разойтись.
| Десятичное | Прямой код | Обратный код | Дополнительный код | Смещённый код | Hex |
|---|---|---|---|---|---|
| 127 | 0111 1111 | 0111 1111 | 0111 1111 | 1111 1111 | 7F |
| 100 | 0110 0100 | 0110 0100 | 0110 0100 | 1110 0100 | 64 |
| 10 | 0000 1010 | 0000 1010 | 0000 1010 | 1000 1010 | 0A |
| 5 | 0000 0101 | 0000 0101 | 0000 0101 | 1000 0101 | 05 |
| 1 | 0000 0001 | 0000 0001 | 0000 0001 | 1000 0001 | 01 |
| 0 | 0000 0000 | 0000 0000 | 0000 0000 | 1000 0000 | 00 |
| -1 | 1000 0001 | 1111 1110 | 1111 1111 | 0111 1111 | FF |
| -5 | 1000 0101 | 1111 1010 | 1111 1011 | 0111 1011 | FB |
| -10 | 1000 1010 | 1111 0101 | 1111 0110 | 0111 0110 | F6 |
| -100 | 1110 0100 | 1001 1011 | 1001 1100 | 0001 1100 | 9C |
| -127 | 1111 1111 | 1000 0000 | 1000 0001 | 0000 0001 | 81 |
| -128 | — | — | 1000 0000 | 0000 0000 | 80 |
| Разрядность | Дополнительный / смещённый код | Прямой / обратный код |
|---|---|---|
| 4 | -8 … 7 | -7 … 7 |
| 8 | -128 … 127 | -127 … 127 |
| 16 | -32768 … 32767 | -32767 … 32767 |
| 32 | -2147483648 … 2147483647 | -2147483647 … 2147483647 |
| 64 | -9223372036854775808 … 9223372036854775807 | -9223372036854775807 … 9223372036854775807 |
Собрано и проверено инженерной командой Go Tools.
11111011 11111011, то есть 0xFB.
-128 … 127 От −128 до 127 в дополнительном коде; от −127 до 127 в прямом и обратном.
значение − 2^n Если старший бит 0 — читайте как беззнаковое; если 1 — вычтите 2^n из беззнакового прочтения.
−1 или 255 −1 как знаковый байт, 255 как беззнаковый. Одни только биты этого не решают.
Дополнительный код (two's complement) отвечает на аппаратный, а не на математический вопрос: как хранить отрицательные числа, чтобы уже построенный сумматор продолжал работать? Приём в том, чтобы представлять −x паттерном значения 2^n − x. Сложение тогда заворачивается по модулю 2^n и попадает в правильный ответ без единого особого случая для знаков — поэтому вычитанию не нужна отдельная схема.
Отсюда следуют два вывода, и оба всплывают в реальных багах. Во-первых, диапазон несимметричен: восемь бит покрывают от −128 до 127, а не до 128, потому что паттерны нужно как-то поделить, а отрицательного нуля, который уравнял бы стороны, здесь нет. Во-вторых, знак — это не флаг, который можно снять: старший бит 11111011 равен 1, но значение равно −5, а не −123, так что прочитать отрицательное число — значит интерпретировать всё слово, а не посмотреть на один бит.
Прямой код (sign-magnitude) и обратный код (ones' complement) — две проигравшие конструкции. Знать их всё равно стоит: плавающая точка IEEE 754 сохранила раскладку прямого кода, а именно сравнение с ними делает дополнительный код неизбежным, а не произвольным.
// -5 as an 8-bit byte, three ways to arrive at the same pattern 0b00000101 // 5 ~0b00000101 // 11111010 ones' complement of 5 ~0b00000101 + 1 // 11111011 two's complement = -5 // In JavaScript the width matters: bitwise operators are 32-bit, // so anything wider has to go through BigInt. BigInt.asIntN(8, 0xFBn) // -5n BigInt.asUintN(8, -5n) // 251n BigInt.asIntN(64, 0xFFFFFFFFFFFFFFFBn) // -5n // C23 made two's complement mandatory for signed integers. // Before that, the other two encodings were legal but unused.
Прямой, обратный, дополнительный и смещённый код считаются вместе. Смещённый код чаще всего и пропускают в калькуляторах — а именно его продолжают использовать даташиты АЦП.
Вставьте те биты или тот hex, что у вас есть, и увидите все пять прочтений, включая беззнаковое. Это то направление, которое нужно, когда дамп расходится с числом, о котором сообщает устройство.
Каждое значение обрабатывается через BigInt, поэтому 0xFFFFFFFFFFFFFF9C разрешается в −100, а не в то, что дало бы 32-битное усечение.
При разрядности 8 у −128 нет ни прямого, ни обратного кода. Таблица так и пишет вместо того, чтобы напечатать паттерн, который этого числа не означает.
Введите 0 — и увидите второй битовый паттерн нуля в прямом и обратном коде. Это самый наглядный отдельный аргумент в пользу того, почему победил дополнительный код.
8-битная сравнительная таблица и диапазоны по разрядностям отрисовываются при сборке страницы тем же движком, который питает живые поля, — поэтому разойтись с ним они не могут.
BigInt.asIntN, питоновский int.from_bytes(..., signed=True) и типы фиксированной ширины в C дают авторитетный ответ для того кода, который вы пишете. Используйте их в коде, а эту страницу — когда значение уже перед глазами, а открытого интерпретатора под рукой нет.
Показывает значение с тем типом, который объявила программа, — ровно той информации битовому паттерну и не хватает. Он не поможет, когда байты пришли по проводу без объявленного типа: как раз для этого случая и нужна эта страница.
Переводит между системами счисления, но только для неотрицательных значений — отрицательные там отклоняются явно, потому что у системы счисления нет мнения о том, как хранится знак. Знаковое представление — задача этой страницы; конвертер систем счисления берите для модулей.
Аналог для плавающей точки. Он сохраняет раскладку прямого кода, а не дополнительного, и смещает порядок на 2^(e−1)−1, поэтому две страницы отвечают на разные вопросы об одном и том же слове памяти.
-5, разрядность 8
прямой код 1000 0101 обратный код 1111 1010 дополнительный код 1111 1011 (0xFB) смещённый код 0111 1011
Три кодировки совпадают в знаковом бите и расходятся во всём остальном. В переменной типа int8_t в C реально лежит только строка дополнительного кода.
0xFB, разрядность 8
беззнаковое 251 прямой код -123 обратный код -4 дополнительный код -5 смещённый код 123
-128, разрядность 8
прямой код нет представления обратный код нет представления дополнительный код 1000 0000 (0x80) смещённый код 0000 0000
Прямой и обратный код тратят по одному битовому паттерну на отрицательный ноль, поэтому охватывают диапазон от −127 до 127 и до −128 не дотягивают. Инструменты, которые печатают здесь байт, ошибаются.
0xFFFFFFFFFFFFFF9C, разрядность 64
дополнительный код -100 беззнаковое 18446744073709551516
Всё, что шире 32 бит, приходится считать через BigInt. Операторы |, << и >>> в JavaScript молча усекают до 32 бит — поэтому некоторые онлайн-калькуляторы возвращают здесь неверный ответ вместо ошибки.
4, 8, 16, 32 или 64. Это не настройка отображения: одни и те же биты при разной разрядности означают разные числа, поэтому ошибка здесь меняет ответ.
Наберите целое число вместе со знаком минуса. Все четыре кодировки обновляются по мере ввода вместе с шестнадцатеричной формой каждой из них.
Вставьте двоичную строку или значение с 0x в поле обратного разбора, чтобы увидеть, что именно этот паттерн означает в каждой интерпретации, включая беззнаковое прочтение.
Страница отмечает два случая, на которых чаще всего спотыкаются: у самого отрицательного значения нет ни прямого, ни обратного кода, а у нуля в этих двух кодировках есть второй битовый паттерн.
Инверсия битов даёт обратный код. Остановиться на этом — значит промахнуться на единицу мимо дополнительного, и ошибку легко не заметить: результат по-прежнему выглядит правдоподобным отрицательным числом.
5 = 00000101 ~5 = 11111010 <- ones' complement, not -5
5 = 00000101 ~5 = 11111010 ~5 + 1 = 11111011 <- -5 in two's complement
JavaScript усекает операнды побитовых операторов до 32 бит. Старшая половина исчезает без всякой ошибки, поэтому результат не отсутствует, а неверен.
0xFFFFFFFFFFFFFFFB // 18446744073709552000 -- the literal is already rounded ~0xFFFFFFFFFFFFFFFB + 1 // 0 -- silently wrong, expected -5
BigInt.asIntN(64, 0xFFFFFFFFFFFFFFFBn) // -5n
Дополнение нулями сохраняет число, только пока оно положительное. Для отрицательного значения знаковый бит нужно размножить по новым битам.
int8 0xFB (-5) int16 0x00FB (251) <- zero-extended
int8 0xFB (-5) int16 0xFFFB (-5) <- sign-extended
У −128 в восьми битах нет ни прямого, ни обратного представления, потому что обе кодировки тратят один паттерн на отрицательный ноль. Напечатать для него 10000000 — значит подменить ответ дополнительного кода кодировкой, которая это число выразить не может.
-128 sign-magnitude: 10000000 <- that pattern means -0
-128 sign-magnitude: no representation at width 8 -128 two's complement: 10000000
0xFF9C. Беззнаково это 65436, что температурой быть не может. При разрядности 16 строка дополнительного кода показывает −100, и с масштабным коэффициентом 0.1 °C датчик сообщает вам −10.0 °C.n−1 бит — модуль, читаемый как обычное беззнаковое число. Диапазон от −(2^(n−1)−1) до 2^(n−1)−1, симметричный, с двумя нулями. Именно эту раскладку IEEE 754 использует для плавающей точки.2^n − 1 − x. Диапазон и те же два нуля, что и у прямого кода. Сложению нужен циклический перенос — именно это усложнение и убирает дополнительный код. В английских названиях положение апострофа не опечатка: ones' complement берётся относительно слова из одних единиц, а two's complement — относительно одной степени двойки.−x хранится как 2^n − x. Диапазон от −2^(n−1) до 2^(n−1)−1, намеренно несимметричный, с одним нулём. Сложение, вычитание и умножение в младшем слове не зависят от знака — в этом вся причина его победы.value + 2^(n−1), поэтому −2^(n−1) превращается в сплошные нули, а паттерны сортируются в том же порядке, что и кодируемые ими значения. Он равен паттерну дополнительного кода с инвертированным старшим битом. Осторожно с названиями: поля порядка IEEE 754 смещены на 2^(e−1)−1 — на единицу меньше, чем смещение здесь.&, |, ~ и сдвигов к 32-битным целым перед операцией и обратно после неё, поэтому 64-битное значение теряет старшую половину, не вызвав ни одной ошибки. Каждое преобразование на этой странице выполняется вместо этого на целых произвольной точности — поэтому и 64-битные крайние значения выходят точными.−(−128) для знакового байта по-прежнему равно −128. Любой код, вычисляющий модуль, должен иметь план на этот вход, и любой набор тестов должен его содержать.0xFB в 16-битное поле как 0x00FB превращает −5 в 251. Расширить знаковое значение — значит размножить знаковый бит, то есть получить 0xFFFB.BigInt.asIntN в JavaScript, int.from_bytes(..., signed=True) в Python и типы фиксированной ширины в C говорят то, что имеют в виду, и обрабатывают края диапазона. Самописный ~x + 1 — вот откуда берутся ошибки с разрядностью.2^n − x: благодаря этому сложение и вычитание выполняет одна и та же схема, а на числовой оси остаётся ровно один ноль. 00000101 → 11111010 → 11111011. Один только шаг инверсии даёт обратный код — поэтому обратный и дополнительный всегда отличаются на единицу. n битах он покрывает от −2^(n−1) до 2^(n−1)−1, потому что не тратит паттерн на отрицательный ноль, как это делают прямой и обратный код. Освободившаяся ячейка достаётся отрицательной стороне. int8_t или uint8_t. value + 2^(n−1): минимальное значение становится сплошными нулями, а сортировка сырых паттернов как беззнаковых чисел совпадает с сортировкой знаковых значений. Он встречается на выходах АЦП и ЦАП и в форматах звуковых отсчётов. Учтите, что поля порядка IEEE 754 используют другое смещение — 2^(e−1)−1, а не 2^(e−1), — так что переносить число между ними нельзя. 65436, тогда как устройство имело в виду −100 в дополнительном коде. Вставьте 65436 как hex 0xFF9C при разрядности 16 — строка дополнительного кода покажет задуманное прочтение. ~x + 1, молча теряет старшую половину 64-битного значения и выдаёт правдоподобный, но неверный результат. Этот инструмент везде работает на BigInt — поэтому 64-битные строки здесь совпадают с тем, что показывает ваш отладчик. 00000000, и 10000000; в обратном — 00000000 и 11111111. Из-за этого два значения, которые должны быть равны, могут оказаться неравными при побитовом сравнении. У дополнительного кода ноль один, и это убрало целый класс аппаратных особых случаев. Конвертеры
Конвертация между системами счисления — двоичной, hex, десятичной, восьмеричной и любой базой 2-36 мгновенно. Бесплатно, приватно — вся обработка в браузере.
Конвертеры
Конвертация прав доступа Linux между восьмеричной записью (755, 644) и символами rwx. Готовые команды chmod и предупреждения о рискованных режимах вроде 777 — бесплатно, прямо в вашем браузере.
Конвертеры
Конвертируйте HEX в RGB, HSL, OKLCH, OKLAB и CMYK прямо в браузере — копируйте любой формат в один клик. Бесплатно, без регистрации, ваши цвета никогда не покидают страницу.
Конвертеры
Конвертируйте HEX-цвета в CMYK прямо в браузере. Наивное приближение на основе sRGB для предпросмотра печати. Бесплатно, без регистрации, ваши цвета остаются локально.
Конвертеры
Конвертируйте любой HEX-цвет в HSL прямо в браузере — поддерживаются 3-значные, 6-значные и 8-значные HEX с альфой. Бесплатно, мгновенно, без регистрации, ваши цвета никогда не покидают страницу.
Конвертеры
Конвертируйте HEX в OKLCH для токенов дизайна Tailwind v4. Живой перцептивно-равномерный вывод с предупреждениями цветового охвата Display P3. Бесплатно, только в браузере.