Считаем до трёх: четыре / Хабр
Это уже четвёртая статья, по мере готовности будет продолжение. Оглавление:
- Считаем до трёх: раз (троичный мультиплексор и сумматоры)
- Считаем до трёх: два (память)
- Считаем до трёх: три (счётчики)
- Считаем до трёх: четыре (однотритный вычислитель и система команд трёхтритного)
Вот так выглядит основная железка, о которой сегодня будет идти речь (больше перемычек богу перемычек!):
Как я и говорил, моя цель — постройка хоть и примитивной, но осязаемой программируемой железки, работающей на троичной логике. Пока что я склоняюсь к следующей системе команд, предложенной тут:
- каждая инструкция будет фиксированной длины (5 тритов)
- два трита на идентификатор инструкции, три трита (одна триада) на её параметр
![](http://xn----8sbanwvcjzh9e.xn--p1ai/wp-content/plugins/a3-lazy-load/assets/images/lazy_placeholder.gif)
NO (-3) — передать управление на ttt (в будущем можно переключать сегменты через регистр R13)
NP (-2) — выполнить OPB ttt (универсальная бинарная команда) над R1 и R2 (две другие триады, задающие команду, берутся из R3 и R4) и установить флаг знака
ON (-1) — выполнить OPA ttt (универсальная унарная команда) над R1 (результат записать в тот же R1) и установить флаг знака
OO (0) — копирование регистров (см. далее)
OP (+1) — записать триаду в регистр R1
PN (+2) — записать триаду в регистр R2
PO (+3) — записать триаду в регистр R3
PP (+4) — записать триаду в регистр R4
Копирование регистров:
OONNN — скопировать R1 в R13
OONNO — скопировать R1 в R12
OONNP — скопировать R1 в R11
OONOO — скопировать R1 в R9
OONOP — скопировать R1 в R8
OOPON — скопировать R1 в R7
OOPOO — скопировать R1 в R6
OOPOP — скопировать R1 в R5
OOONN — скопировать R1 в R4
OOONO — скопировать R1 в R3
OOONP — скопировать R1 в R2
OOOON — декремент R1 и установить флаг знака
OOOOO — проверить R1 и установить флаг знака
OOOOP — инкремент R1 и установить флаг знака
OOOPN — скопировать R2 в R1
OOOPO — скопировать R3 в R1
OOOPP — скопировать R4 в R1
OOPNN — скопировать R5 в R1
OOPNO — скопировать R6 в R1
OOPNP — скопировать R7 в R1
OOPON — скопировать R8 в R1
OOPOO — скопировать R9 в R1
OOPOP — скопировать R10 в R1
OOPPN — скопировать R11 в R1
OOPPO — скопировать R12 в R1
OOPPP — скопировать R13 в R1
Обратите внимание, что копирование производится только из/в регистр R1.
Память инструкций будет выполнена трёхпозиционными переключателями. Поскольку непосредственный параметр инструкции трёхтритный, то память команд будет адресоваться только тремя тритами, что даёт 27 инструкций, что мало. Посему будет несколько сегментов памяти инструкций, а регистр R13 будет использоваться для переключения между сегментами, что даёт шеститритную шину адреса, и реальное количество памяти команд будет ограничиваться только тем, насколько я устану эту память паять.
Один сегмент памяти команд будет набран из пятнадцати вот таких платок:
Каждая из таких платок несёт на себе 9 трёхпозиционных переключателей, для наглядности (особенно на фото) команды подсвечиваются двухцветными светодиодами.
Но прежде чем бросаться в пайку гигантских количеств (несколько сотен) тримуксов, давайте сначала попробуем сделать какой-нибудь существенно более простой вычислитель просто в качестве подтверждения того, что на этом принципе можно что-то построить.
Итак, упростим до максимума. Наш вычислитель будет иметь всего девять команд, каждая из которых задаётся старшим тритом I и младшим тритом J:
IJ
NN — скопировать R1 в R4
NO — скопировать R1 в R3
NP — скопировать R1 в R2
ON — декремент R1 и установить флаг знака
OO — проверить R1 и установить флаг знака
OP — инкремент R1 и установить флаг знака
PN — скопировать R2 в R1
PO — скопировать R3 в R1
PP — скопировать R4 в R1
Девятью командами получается адресовать максимум четыре регистра памяти, так что памяти будет четыре однотритных регистра и флаг знака. Памяти команд в вычислителе не будет вообще, а значит, и указатель текущей команды (счётчик) не нужен.
Собираем регистры
Железку я буду собирать и тестировать каждую её часть отдельно. Во-первых, при таком количестве и плотности проводов очень велика вероятность ошибки монтажа, а во вторых, наши восточные партнёры зачастую продают не очень качественные перемычки 🙂
Итак, у нас будут четыре одинаковые ячейки памяти с запоминанием по уровню, мы их подробно рассмотрели во второй статье:
Выводить наружу доступ ко всем ячейкам затруднительно и нерационально, поэтому они будут адресоваться через мультиплексор один-к-четырём. Разумеется, это просто урезанная версия мультиплексора 1-к-9. В итоге схема нашей памяти выглядит следующим образом:
То есть, память регистров — это железка, которая на вход берёт два трита адреса, а на выход предоставляет ноги C,A,Q соответствующей ячейки памяти. Вот видео тестирования доступа к регистрам:
Адресуем правильные регистры в нужный момент
Всё копирование регистров будет происходить через промежуточный буфер. То есть, сначала содержимое регистра копируется в буфер, а затем буфер копируется в конечный регистр.Мой однотритный компьютер будет тактироваться троичной пилой, по отрицательному уровню будет происходить копирование в буфер, а по положительному обратно из буфера в память.
Вот эта схема позволяет адресовать нужный регистр памяти в нужный момент в зависимости от номера инструкции IJ и сигнала троичной пилы CLK.
Красные мультиплексоры генерируют адрес ячейки, ИЗ которой копировать, зелёные мультиплексоры дают адрес ячейки, В которую происходит запись.
Вот видео тестирования работы схемы адресации памяти:
Непосредственно копирование
Поскольку генерирование нужных адресов памяти происходит само при помощи вышеописанной схемы, то для того, чтобы не загромождать схему, мы можем забыть про то, что у нас четыре регистра, и представить, что памяти только один регистр + буфер.
Копирование из регистра в буфер и обратно можно сделать крайне примитивно:
По отрицательному сигналу CLK на ногу C буфера придёт -1, а на ноге C памяти будет 0, что означает, что буфер запомнит то, что будет ему подано на ногу A. По положительному сигналу CLK всё с точностью до наоборот, скопируем содержимое буфера назад в память.
Теперь осталось вспомнить, что у нас есть не только команды копирования, но и команды увеличения/уменьшения регистра R1 на единицу. Конечная схема нашего компьютера выглядит так:
Когда старший трит команды ненулевой, то выход Q буфера подаётся напрямую на вход A памяти. Когда же он нулевой, то выход Q буфера подаётся в память через полусумматор (схему полусумматора смотрите в первой статье). Аналогично происходит и установка флага знака.
Ну а вот так выглядит железка в сборе:
А вот видео её тестирования:
Тестировать каждый кирпичик отдельно очень полезно, вот все дохлые перемычки, которые были найдены в процессе сборки только этой железки (привет нашим восточным партнёрам!)
В принципе, как собирать конечный трёхтритный вычислитель вполне ясно, надо только собраться с духом и это сделать, причём, разумеется, не на макетке, так как по грубым оценкам мне на него понадобится сотни три-четыре тримуксов.
Если грубо, то АЛУ трёхтритного вычислителя будет содержать три раза последнюю схему (по одной на каждый трит). На этом, конечно, не заканчивается, так как АЛУ будет содержать по отдельной схеме на каждую команду. Итого нужно разработать остаток АЛУ, добавить ещё регистров, добавить счётчик команд, память инструкций и непосредственно схему дешифратора инструкций. Ничего неподъёмного.
Буду рад услышать новые идеи и замечания!
играем с эмулятором / Хабр
Как я и говорил, я потихоньку строю очень простой, но функциональный и при этом бескомпромиссно троичный вычислитель, основанный на сбалансированной троичной системе счисления. В этой статье я описываю эмулятор моего вычислителя, который мне поможет в отладке железа. Если вам интересно, не стесняйтесь писать под него программы, я их обязательно запущу на настоящем железе как только оно будет готово! Это очень просто, Триадор понимает обычный очень примитивный императивный язык, схожий с ассемблером или brainfuck 🙂
— Жуткий кошмар! Нули и единицы повсюду. И кажется, я видел двойку.
— Это просто сон, Бендер. Двоек не бывает.
И ведь это не шутка, в моём троичном вычислителе действительно нет двоек! Следите за мини-сериалом о постройке моего вычислителя на ютубе, а пока железо зреет, давайте разбираться с архитектурой и писать под неё первые программы!
Триадор имеет трёхтритную архитектуру, это означает что его регистры могут хранить целые числа от -13 до +13. Он имеет четыре основых регистра R1-R4 и девять дополнительных регистров R5-R13. Обратите внимание, что R13 — это регистр специального назначения, он используется для выбора сегмента памяти программ (подробнее об этом ниже). Таким образом, Триадор может хранить в своей памяти 13 целых чисел из диапазона [-13..+13]. В дополнение к этому, он несёт на себе однотритный флаг переполнения/переноса и шеститритный счётчик команд. Доступная только для чтения память программ состоит из 27 сегментов по 27 инструкций каждый. Таким образом, максимальный объём программы для Триадора составляет 729 инструкций. Вот краткое описание архитектуры Триадора:
У Триадора очень ограниченный набор инструкций, он очень близок к брейнфаку в терминах удобства программирования, но предлагает гораздо более читаемый код (чуть ниже будут примеры).
Триадор понимает 9 команд простейшего императивного языка, каждая инструкция сопровождается обязательным трёхтритным аргументом. Обратите внимание, что инструкция расширения EX ttt на данный момент интерпретируется как halt and catch fire. Вот полный список доступных команд:
git clone https://github.com/ssloy/triador.git cd triador mkdir build cd build cmake .. make ./triador ../prog/add.txt
Вы также можете открыть проект в гитподе:
По открытии, редактор скомпилирует и выполнит программу на одном из примеров. Просто меняйте текст примера в редакторе и перезапускайте программу (используйте историю команд из терминала).
Файл с программой обязан содержать одну инструкцию на каждой строке. Инструкция обязана состоять из шести символов и находиться в начале строки. Все символы после шестого игнорируются. То есть, начало каждой строки должно содержать одну из следующих инструкций, где ttt означает трёхтритное число от NNN (-13) до PPP (+13):
- EX ttt
- JP ttt
- SK ttt
- OP ttt
- RR ttt
- R1 ttt
- R2 ttt
- R3 ttt
- R4 ttt
Интерпретатор выдаёт на экран полное состояние Триадора для каждого этапа вычислений.
Обратите внимание, что Триадор не имеет интерфейсов типа мышки или даже клавиатуры. Для того, чтобы ввести данные в вычислитель, нужно использовать команды R1-R4.
Сложение
Итак, я хочу сложить два числа, записанные в регистры R2 и R3. Но Триадор не умеет складывать числа! Он умеет делать инкремент/декремент. Насколько это страшно? Да ничуть!
Давайте для начала напишем простейшую программу в знакомой вам обстановке. Я для начала предполагаю, что R2 и R3 неотрицательны. Если я у меня есть операция инкремента/декремента, то мне вполне хватит декрементировать R2 и инкрементировать R3 одновременно до тех пор, пока R2 не достигнет нуля:
int main() { unsigned int R2 = 2; unsigned int R3 = 11; while (R2!=0) { R3++; R2--; } return R3; }
Отлично, а могу ли я складывать числа со знаком? Да никаких проблем, мы самую малость изменим наш код таким образом, чтобы на каждой итерации модуль числа R2 уменьшался на единицу:
int main() { int R2 = -2; int R3 = 13; while (R2!=0) { if (R2>0) R3++; if (R2<0) R3--; if (R2>0) R2--; if (R2<0) R2++; } return R3; }
Ну, собственно, и всё. А теперь переходим непосредственно к Триадору. Добавим последний штрих: Триадор умеет инкрементировать/декрементировать исключительно регистр R1. Ну и ладно, если мы захотим прибавить к R3 единицу, скопируем его в R1, вызовем команду инкремента, и скопируем R1 назад в R3!
Вот очень простая программа, которая пишет два числа в регистры R2 и R3 и вычисляет их сумму. Результат хранится в R3:
Левый столбец (первые шесть символов каждой строки) — это непосредственно программа для Триадора. Счётчик команд инициализирован как NNN NNN, что равно -364 в десятичной системе и соответствует первой строке нашего файла программы. Отметим, что все символы после шестого игнорируются интерпретатором, можно считать, что это комментарии.
Вот лог запуска нашей программы:
$ ./triador ../prog/add.txt | tail -n 3 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 C PC 11 0 11 5 0 6 -12 -2 11 8 11 -10 -13 0 -345
Обратите внимание, что R3 содержит 11, результат операции -2 + 13.
Разумеется, Триадор не поддерживает циклы типа while напрямую, он использует безусловные джампы, JP, ну а ветвление обеспечивается при помощи операции SK, которая позволяет пропустить следующую за ней операцию.
Тонкий момент: обратите внимание, что команда безусловного джампа JP ttt имеет трёхтритный аргумент ttt, в то время как программный счётчик у нас шеститритный. Откуда берутся недостатющие три трита? Из регистра R13! Команда JP ttt перепрыгивает на инструкцию номер 27*R13 + ttt. Иными словами, перепрыгивает на команду номер ttt сегмента с номером, взятым из регистра R13. Самый первый сегмент памяти команд имеет номер NNN (-13), и именно поэтому первые две строчки моей программы выглядят как
R1 NNN # write -13 to R1 RR NNN # copy R1 to R13
Поскольку мой код влезает целиком в один сегмент, я больше не трогаю R13, и джампы прыгают только в пределах сегмента NNN.
Сложение с контролем переполнения
Предыдущий код складывает два трёхтритных числа, но ведь сумма двух трёхтритных чисел может не влезть в три трита памяти. Поэтому давайте напишем программу, которая складывает два трёхтритных числа, но результат будет шеститритным. Следующая программа складывает регистры R2 и R3, и записывает результат в регистры R3 и R4: результат равен R3 + R4*27, то есть, R4 может быть равен -1, 0 or 1.
$ ./triador ../prog/add-with-overflow-control.txt |tail -n 3 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 C PC -12 0 -12 1 -9 2 -12 -6 4 5 6 7 -13 0 -338
Обратите внимание, что R3 + 27 * R4 равно 15, результату операции 2+13. По сравнению с предыдущей программой я всего-навсего добавил запись в регистр R4 флага переполнения C:
[...] SK OOO # skip if C==0 JP OPO # overflow ───────┐ JP PNO # no overflow ────│─┐ R4 OOP # write 1 to R4 <─┘ │ SK OOP # skip if C==1 │ R4 OON # write -1 to R4 │ RR OPN # copy R2 to R1 <───┘ [...]
Шеститритное сложение
Вам кажется, что регистры с диапазоном [-13..+13] недостаточно экспрессивны? Никаких проблем, давайте введём тип данных word (на самом деле, мы его уже ввели в предыдущем примере). Эта программа записывает одно шеститритное число в регистры R1,R2 и другое в регистры R3,R4. Затем считает сумму, сохраняя в шеститритном числе R4,R5.
$ ./triador ../prog/long-add.txt |tail -n 3 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 C PC 3 0 0 -6 3 -13 1 3 6 5 13 -2 -13 0 -335
Обратите внимание, что R4+27 * R5 = 75, а мы попросили наш вычислитель посчитать 331-256. Надо ли объяснять, как работает этот код? Если вы разобрались с предыдущими двумя, думаю, ни к чему. Мы считаем сумму двух старших полуслов, затем сумму младших полуслов. Если при суммировании младших полуслов произошло переполнение, нужно добавить или отнять единицу от суммы старших полуслов. Если все эти слова трудно понимать, смотрите эквивалентный код на C++ 🙂
В этом коде только одна тонкость: поскольку мне дважды нужно считать сумму двух трёхтритных чисел, я пытаюсь сымитировать вызов функции. Триадор не знает стеков, триадор не знает сабрутин и адресов возврата. Но мы тоже не лыком шиты! Регистр R7 контролирует, в какое место кода нужно возвратиться из этой эрзац-сабрутины. Если очень грубо, то я храню в регистре R7 адрес возврата из функции:
[...] SK ONO # skip if R1!=0 JP OON # sub return 1 JP POP # sub return 2
Наибольший общий делитель
Разумеется, наш набор примеров был бы неполон без Евклидова алгоритма. Эта программа вычисляет наибольший общий делитель чисел, записанных в регистры R2 и R3. Результат сохраняется в регистре R2.
Давайте разберём, как она работает, для начала в привычном мире C++. Если мы предположим, что числа R2 и R3 положительны, то возможная имплементация алгоритма Евклида выглядит следующим образом:
int main() { int R2 = 12, R3 = 8; while (true) { if (R2==R3) break; if (R2>R3) R2 = R2 - R3; else R3 = R3 - R2; } return R2; }
Насколько всем очевидно, что эта программа вычисляет наибольший общий делитель? Начнём с того, что она точно останавливается: на каждой итерации мы обновляем либо R2, либо R3; одно из них обязательно уменьшается, оставаясь положительным. Если число m делит R2 и делит R3, как это делает наибольший общий делитель, то вполне очевидно, что оно же делит и разницу R2-R3. Если это неочевидно, то запишите R2 = a m, R3 = b m и убедитесь в том, что R2-R3 = (a-b) m. Как-то так.
А что делать, если на вход мы можем получить числа со знаком? А просто взять от них модуль 🙂 Посмотрите сами: этот код абсолютно эквивалентен предыдущему, если он на вход получит положительные числа. Ну а если отрицательные, то модуль нам поможет!
int main() { int R2 = 12, R3 = -8; while (true) { if (R2<0) R2 = -R2; if (R3>0) R3 = -R3; if (R2==-R3) break; int R4 = R2 + R3; if (R4>0) R2 = R4; else R3 = R4; } return R2; }
В итоге программа для Триадора работает именно по этому принципу:
Вот лог исполнения программы:
$ ./triador ../prog/gcd.txt |tail -n 3 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 C PC -13 4 -4 0 4 12 13 1 -7 -9 3 4 -13 0 -338
Обратите внимание, что R2 хранит 4, наибольший общий делитель 12 и -8.
Программировать мой троичный вычислитель ничуть не сложнее, нежели какой-нибудь калькулятор типа МК-61, да и троичность никак не сказывается на принципах построения программ. Второй сезон моего микросериала будет посвящён построению арифметико-логического устройства. Ну а пока санитарные волнения не позволяют хорошо продвигаться с железом, можно отвести душу с эмулятором. Предлагайте ваши варианты решения вышеозначенных задач, предлагайте новые интересные задачи, давайте веселиться!
Stay tuned.
One’s Complement Calculator
Создано Филиппом Маусом
Отзыв Стивена Вудинга
Последнее обновление: 02 февраля 2023 г.
Содержание:- Что такое двоичные числа?
- Как преобразовать отрицательные десятичные числа в двоичные – метод дополнения до единицы.
- Как пользоваться калькулятором дополнения до единицы?
- Преобразование дополнения в десятичное число.
Добро пожаловать в калькулятор дополнения до единицы (или калькулятор дополнения до единицы). Этот инструмент поможет вам ** найти отрицательный эквивалент каждой положительной двоичное число и показывает , как преобразовать десятичное число в дополнение до . Вы узнаете , как преобразовывать отрицательные десятичные значения в двоичные числа и , как вычислять дополнение до единицы .
Что такое двоичные числа?
Чтобы понять двоичную систему счисления, давайте сравним ее с десятичной системой счисления, которую мы используем в повседневной жизни.
В десятичной системе числа состоят из цифр от 000 до 9.01⋅22+0⋅21+1⋅20. Двоичный преобразователь в Omni Calculator глубоко анализирует эту тему, не пропустите!
Но это двоичное представление оставляет много проблем, которые мы можем легко решить для десятичной системы: если мы можем использовать только цифры 000 и 111, как мы можем выразить отрицательные числа в двоичной системе? Как мы вычисляем бинарное сложение? И как мы вычитаем двоичные числа?
Как преобразовать отрицательные десятичные значения в двоичные – метод дополнения до единицы.
![](/800/600/http/cf2.ppt-online.org/files2/slide/3/3eE9wsLJCZUmtkbcFAolqig6WfNDpnSaud2BhYj5M/slide-3.jpg)
Прежде чем мы сможем использовать калькулятор дополнения до 1, мы должны понять , как вычисление дополнения до единицы помогает нам преобразовывать отрицательные десятичные значения в двоичные .
Существует несколько способов представления отрицательных двоичных чисел, но все они имеют одну общую основную идею: они используют первый, так называемый старший бит , в качестве бита со знаком. 000 в этом бите указывает на положительное число, а 111 на отрицательное. Использование первого бита в качестве бита со знаком, конечно, изменяет диапазон чисел, выраженных с помощью определенного количества битов. В то время как 8-битное число без знака находится в диапазоне от 000 до 255255255 , 8-битное число со знаком может выражать диапазон от -128-128-128 до 127127127 .
Наиболее интуитивный подход состоит в том, чтобы создать отрицательное двоичное число, просто перевернув первый бит положительного эквивалента.
Итак, поскольку десятичное число 333 равно 001100110011, −3-3−3 равно 101110111011. К сожалению, этот подход не выдерживает базового теста сложения 333 и −3-3−3, поскольку результатом будет 111011101110, что, конечно, не 000.
Этот калькулятор дополнения до 1 использует метод дополнения до единицы для вычисления отрицательных двоичных чисел. Этот метод утверждает, что для определения отрицательного двоичного числа вы берете положительный эквивалент, инвертируете знаковый бит, а затем инвертируете все остальные биты . Таким образом, хотя 333 по-прежнему равно 001100110011, −3-3−3 теперь равно 110011001100. Сложение теперь даст 100010001000, что лучше, но все же не идеально.
Метод дополнения до двух решает проблему сложения удовлетворительно. Узнайте больше об этой теме в нашем калькуляторе дополнения до двух.
Как пользоваться калькулятором дополнения до единицы?
Теперь, когда мы знаем, как вычислить дополнение до единицы, давайте посмотрим на , как использовать калькулятор . В этом примере мы найдем дополнение до единицы для десятичного значения 878787.
Выберите количество битов . В нашем примере хорошим выбором будет 8 бит, поскольку они позволяют использовать диапазон от −128-128−128 до 127127127.
Введите свое десятичное значение в поле ввода в разделе преобразования десятичного числа в двоичное . Калькулятор выводит наше число 878787 и его двоичное представление 0101 01110101\ 01110101 0111.
Калькулятор представляет вам результат : 1010 10001010\ 10001010 1000. Как мы видим, это соответствует ранее описанному методу, переворачивая первый бит со знаком, чтобы указать отрицательное число, и все остальные биты, чтобы получить дополнение до единицы.
Преобразование дополнения в десятичное число.
Калькулятор дополнения до единицы может не только преобразовывать десятичную дробь в дополнение, но и дополнение до десятичного числа . Итак, найдем десятичное значение дополнения до единицы 1011 10011011\ 10011011 1001.
Выберите количество битов . Поскольку наше двоичное число состоит из 8 цифр, мы выбираем 8 бит.
Введите ваше дополнительное значение в поле ввода в двоично-десятичном разделе . Калькулятор отображает наше двоичное значение и его дополнение 0100 01100100\ 01100100 0110, что достигается перестановкой всех битов для двоичного входного значения.
Калькулятор представляет вам результат : −70-70−70.
Ищете комплексный инструмент для решения всех проблем с бинарными файлами? Наш бинарный калькулятор позаботится об этом!
Филип Маус
Представление двоичного числа
Преобразование десятичного числа в двоичное
Вы можете ввести десятичное число от -128 до 127.
Десятичное число
Преобразование двоичного числа в десятичное . Вам не нужно вводить лидирующие нули.
Двоирный
Проверьте 10 аналогичных двоичных калькуляторов 1️0️
Двоирный дополнение. Действие. содержание:
- Что такое битовый сдвиг влево и битовый сдвиг вправо?
- Как использовать калькулятор сдвига битов?
- Часто задаваемые вопросы
Калькулятор сдвига битов позволяет выполнять бит сдвигается влево, а бит сдвигается вправо . Операция логического сдвига может быть выполнена с вводом данных из двоичной, восьмеричной и десятичной систем счисления, а калькулятор выдает результаты в представлении со знаком и без знака.
Что такое битовый сдвиг влево и битовый сдвиг вправо?
Битовый сдвиг — это побитовая операция, выполняемая над двоичным числом . Чтобы лучше понять это, давайте рассмотрим концепцию шаг за шагом.
Двоичные числа — это числа, основанные на системе с основанием 2 . Вы можете освежить свои знания об этой другой системе счисления в двоичном конвертере. Основание 2 означает, что каждая цифра может иметь только значения 000 и 111, представляющие бит, наименьшую единицу цифровой информации. Один бит может отображать только два логических состояния: включено или выключено. Чтобы составить большие объемы информации, биты выстраиваются в ряд, образуя двоичные числа. С ними арифметические операции, такие как двоичное вычитание, могут выполняться без проблем.
Двоичные числа могут быть преобразованы в числа в десятичной системе. В случае отрицательных чисел в десятичной системе существует так называемое знаковое представление, позволяющее отображать числа в двоичной системе.
Так что же такое битовый сдвиг? Битовый сдвиг — это операция, при которой последовательность битов перемещается либо влево, либо вправо . Для логических битовых сдвигов биты, сдвинутые за пределы области действия двоичного числа, теряются, а нули сдвигаются на другом конце. Это отличает этот метод от циклического и арифметического сдвига битов . Битовые сдвиги — не единственные побитовые операции; еще более важными являются AND, OR и XOR: познакомьтесь с ними в калькуляторе логических вентилей Omni и побитовом калькуляторе! 901⋅24+1⋅22+1⋅20.
- Сдвиг вправо сдвигает каждый бит ввода на одну позицию вправо . Таким образом, младший бит теряется, а на другом конце вставляется 000.
- Сдвиг бита влево перемещает каждый бит ввода на одну позицию влево . Справа вставляется 000, чтобы заполнить последовательность битов.
Битовый сдвиг является важной операцией для эффективного выполнения математических операций . В приведенном выше примере мы сдвинули двоичное число 0001 01010001\ 01010001 0101, или 212121 в десятичной системе, на один бит влево. Результатом будет 0010 10100010\ 10100010 1010, или 424242 в десятичной системе. Таким образом, сдвиг на один бит влево равен умножению числа на коэффициент 222 . Сдвиг на два бита означает умножение на 444, 333 бита на 888 и так далее. Эта концепция также работает и наоборот: битовый сдвиг вправо равен делению на 222. Кроме того, битовые сдвиги также важны для области регистров цифровой электроники.
Как использовать калькулятор сдвига битов?
Теперь вы знаете, что такое битовый сдвиг и как выполнить логический сдвиг . Итак, давайте посмотрим на как использовать калькулятор сдвига битов . В качестве примера выполним битовый сдвиг влево. Мы сдвигаем число 272727 в десятичной системе на 222 бита влево , используя инструмент как калькулятор сдвига влево.
- Выберите количество битов в двоичном представлении . Поскольку 8 бит позволяют вводить числа в диапазоне от -128-128-128 до 127127127 в десятичной системе, этого достаточно для нашего дела.
- Выберите тип входных данных. Калькулятор сдвига битов поддерживает числа из двоичной , восьмеричной и десятичной систем.
Мы выбираем десятичную.
- Введите свои данные в поле Число в соответствующей системе счисления. Для нашего примера мы поместим здесь 272727.
- Выберите направление переключения , влево или вправо , чтобы использовать инструмент как калькулятор сдвига влево или калькулятор сдвига вправо. Мы выбираем Левый.
- Калькулятор сдвига битов представляет ваш результат в виде чисел из двоичной, десятичной и восьмеричной систем :
- двоичный: 0110 11000110\ 11000110 1100
- восьмеричный: 154154154
- десятичный: 108108108
🙋 Omni также здесь, чтобы помочь вам с преобразованием между другими системами: попробуйте наш преобразователь десятичной системы в восьмеричную и двоичную в восьмеричную, чтобы узнать, как мы выполнили эти последние преобразования!
Если ваш двоичный результат начинается с 111 и, следовательно, может быть интерпретирован как положительный результат в записи без знака или как отрицательный результат в записи со знаком, будут отображены оба результата.
Часто задаваемые вопросы
Что такое битовый сдвиг?
Сдвиг битов описывает операцию сдвига строки битов на определенное количество позиций влево или вправо . Например, двоичное число 0001 0101
, сдвинутое на 1 бит влево, равно 0010 1010
.
Как рассчитать сдвиг влево на 3 бита?
Чтобы вычислить сдвиг влево на 3 бита , выполните следующие действия:
- Получите свое число в двоичном формате , например,
0000 0101
. - Сдвиньте битовую строку на 3 позиции влево , отбросив цифры, выпадающие из области видимости, и заполнив справа нулями:
0010 1000
. - Вот и все; вы выполнили сдвиг на 3 бита влево .
Что такое логический сдвиг битов?
Логический битовый сдвиг — это операция, при которой последовательность битов сдвигается влево или вправо на определенное число позиций , а пустые цифры двоичного числа заполняются нулями.