Этот тренажёр — пара к конвертеру систем счисления: конвертер переводит за вас, тренажёр учит переводить самому. Задачи взяты из того, что встречается при работе с микроконтроллерами: байты и 16-битные слова, знаковые типы int8_t и int16_t, маски регистров.
Три типа задач
Перевод. Число в одной из систем — двоичной, десятичной или шестнадцатеричной — нужно записать в другой. Позиционный вес разряда — степень основания, поэтому двоичное число равно сумме весов единичных битов (Kuphaldt, т. IV, гл. 1):
Между двоичной и шестнадцатеричной системами переводят группами по четыре бита: 1011 01112 = B716.
Дополнительный код. В N-битном слове старший бит весит −2N−1, а остальные — как обычно (Kuphaldt, т. IV, гл. 2):
Отсюда правило «инвертировать и прибавить единицу» для записи −x и обратное правило для чтения: если старший бит равен 1, из беззнакового значения вычитают 2N. Так же работает команда NEG у AVR — она вычитает регистр из нуля (DS40002198B, 6.80).
Битовые операции. AND, OR, XOR и NOT применяют таблицу истинности к каждому разряду отдельно, сдвиги переносят все биты на n позиций. В C операнды типов uint8_t и uint16_t сначала проходят целочисленное продвижение — превращаются в int или, если int их не вмещает, в unsigned int (N1570, 6.3.1.1). Поэтому сдвиг влево считается в более широком типе как умножение на 2n, и лишние старшие биты отбрасывает только приведение результата обратно к uint8_t или uint16_t — остаток по модулю 2N (6.3.1.3); отсюда (uint8_t) в условиях задач. Сдвиг вправо для неотрицательного числа — целая часть деления на 2n (6.5.7). Сюда же входят три приёма, без которых не обходится ни один драйвер: установка бита x | (1 << n), сброс x & ~(1 << n) и переключение x ^ (1 << n). Константа 1 имеет тип int, а у AVR int 16-битный, так что 1 << 15 уже не помещается в него — для 16-битных масок тренажёр пишет 1u << n. Их применение к портам — в уроке «Порты и регистры».
Какие ошибки тренажёр узнаёт
| Ответ | Что случилось |
|---|---|
| обратный код (биты инвертированы, единица не прибавлена) | −5 → 0xFA вместо 0xFB |
| код модуля | −5 → 0x05: знак потерян |
| прямой код со знаковым битом | −5 → 0x85: знак и модуль, а нужен дополнительный код |
| значение без знака вместо знакового | 0xDB → 219 вместо −37 |
| биты в обратном порядке | младший бит прочитан слева |
| число не помещается в разрядность | например, −129 для int8_t |
На остальные неверные ответы тренажёр просто говорит «неверно» — исправьте ответ или откройте решение по шагам.
Как пользоваться
- Выберите тип задач и разрядность. Начните с 8 бит — числа короче, ошибиться труднее.
- Ответ вводится в системе, указанной в задаче. HEX можно писать с
0xи без, в любом регистре, двоичное — с0b, пробелами и подчёркиваниями:1011 0111и0b1011_0111одинаково верны. Десятичное знаковое — с минусом. - «Показать решение» выводит шаги: веса битов, группы по четыре, инверсию и прибавление единицы, операцию столбиком.
- У каждой задачи есть номер варианта — ссылка из кнопки под тренажёром откроет ту же задачу у другого человека.
Длинную арифметику — сложение, вычитание и флаги переноса и переполнения — разбирает калькулятор двоичной арифметики, а маски для регистров удобно собирать в калькуляторе битовых масок.
Частые вопросы
Как быстро перевести двоичное число в шестнадцатеричное?
Разбейте его на группы по четыре бита справа и замените каждую группу шестнадцатеричной цифрой: 1011 0111 — это B7. Обратно так же: каждая цифра HEX — четыре бита, F — 1111, 9 — 1001. Через десятичную систему переводить не нужно — именно поэтому в коде для микроконтроллеров регистры пишут в HEX.
Как записать отрицательное число в дополнительном коде?
Запишите модуль числа нужной разрядностью, инвертируйте все биты и прибавьте 1. Для −5 в восьми битах: 00000101 → 11111010 → 11111011, то есть 0xFB. Если забыть прибавить единицу, получится обратный код 0xFA — тренажёр узнаёт эту ошибку и подскажет.
Как понять, какое число записано в int8_t, например 0xDB?
Посмотрите на старший бит. Если он 0, число положительное и равно своему значению. Если 1, вычтите 2⁸ = 256 из беззнакового значения: 0xDB = 219, 219 − 256 = −37. Для int16_t вычитают 65 536. Ответ 219 тренажёр отметит как типичную ошибку: это значение без знака.
Чем этот тренажёр отличается от конвертера систем счисления?
Конвертер переводит число, которое вы ввели, — для работы с регистрами и отладки. Тренажёр, наоборот, сам задаёт число и ждёт ваш ответ: он нужен, чтобы научиться переводить в уме и на бумаге, как на контрольной или собеседовании. Для проверки своих вычислений вне тренажёра пользуйтесь конвертером.
Источники
- Kuphaldt T. R. Lessons In Electric Circuits, Vol. IV — Digital, ch. 1 «Numeration Systems» (CC BY) — позиционные веса — степени основания; пример 11001101₂ = 205₁₀; шестнадцатеричная цифра — четыре бита, восьмеричная — три, группы считают от запятой; пример 10110111,1₂ = B7,8₁₆
- Kuphaldt T. R. Lessons In Electric Circuits, Vol. IV — Digital, ch. 2 «Binary Arithmetic» (CC BY) — старший бит имеет отрицательный вес; дополнительный код — инвертировать все биты и прибавить 1; −5 в четырёх битах — 1011, в восьми — 11111011; −25 в шести битах — 100111, 18 + (−25) = −7; положение знакового бита задают до перевода
- Kuphaldt T. R. Lessons In Electric Circuits, Vol. IV — Digital, ch. 3 «Logic Gates» (CC BY) — таблицы истинности AND, OR, XOR и NOT — побитовые операции применяют их к каждому разряду
- Microchip. AVR Instruction Set Manual, DS40002198B — 6.80 NEG: Rd ← 0x00 − Rd, дополнительный код регистра; значение 0x80 остаётся 0x80
- ISO/IEC 9899:201x (C11), Committee Draft N1570 — 6.3.1.1 — целочисленное продвижение: типы ранга ниже int становятся int, а если int не вмещает все их значения — unsigned int; 6.3.1.3 — приведение к беззнаковому типу берёт значение по модулю максимума типа плюс 1; 6.5.3.3 — побитовое дополнение ~; 6.5.7 — для беззнаковых E1 << E2 равно E1·2^E2 по модулю максимума типа плюс 1, для знакового — неопределённое поведение, если E1·2^E2 не помещается в тип; E1 >> E2 — целая часть E1/2^E2; 6.5.10–6.5.12 — побитовые &, ^, |
Где пригодится
Встроить калькулятор на свой сайт
Скопируйте код и вставьте его в HTML страницы, статьи или вики. Виджет бесплатный, без рекламы, счётчиков и cookie. Условие одно — ссылка на GAW под рамкой остаётся на месте. Подробнее о виджетах
<iframe src="https://gaw.ru/embed/number-trainer/" title="Тренажёр: системы счисления, дополнительный код и биты" width="100%" height="640" style="border:1px solid #e3e5e9;border-radius:8px" loading="lazy" allow="clipboard-write"></iframe>
<p style="margin:6px 0 0;font-size:14px">Калькулятор: <a href="https://gaw.ru/tools/number-trainer/">Тренажёр: системы счисления, дополнительный код и биты</a> — GAW.ru</p>Автоподстройка высоты рамки
Если сайт разрешает скрипты, добавьте этот код один раз в любом месте страницы: рамка будет менять высоту вместе с результатом расчёта.
<script>window.addEventListener("message",function(e){if(e.origin!=="https://gaw.ru"||!e.data||e.data.type!=="gaw:embed-height")return;var f=document.querySelectorAll('iframe[src^="https://gaw.ru/embed/"]');for(var i=0;i<f.length;i++)if(f[i].contentWindow===e.source)f[i].style.height=e.data.height+"px"})</script>Обновлено .
Нашли ошибку в расчёте?