Операции с битами
Иногда бывает необходимо изменить отдельные разряды в числе. Например, компьютер TRS-80 определяет, занят ли принтер, по состоянию одного разряда (включен-выключен), точно так же ЭВМ TRS-80 и IBM PC определяют состояние телекоммуникационной связи через модем по состоянию (статусу) нескольких битов в трех байтах. Так, если один определенный бит установлен в "1", то данные принимаются по телефонной линии, но если этот бит сброшен в "0", то линия свободна и можно передавать данные. Поэтому зачастую полезно иметь возможность просматривать состояние, а также изменять значения отдельных битов. В оставшейся части этого раздела мы будем использовать компьютер для ввода и вывода двоичных чисел, поэтому вам нужно установить двоичное основание, т.е. записать в переменную BASE число 2. Если вашему компьютеру известно слово BINARY, то достаточно ввести это слово. (Если вы не уверены, попробуйте его, худшее, что может произойти, -- это получение сообщения об ошибке.) Если слово BINARY у вас не работает, введите
2 BASE !
Теперь, если вы попытаетесь ввести цифру больше 1, Форт будет отвергать ее как не имеющую смысла в двоичной системе счисления. Представим себе, что в стеке находится двоичное число 10011111 и вы хотите изменить третий справа разряд в "0", т.е. вы хотите превратить это число в 10011011. Слово AND (И) позволит вам сделать это. Слово AND сравнивает поразрядно два числа, и если в обоих (одном и другом) эти разряды установлены в "1", то результат будет 1, иначе результатом будет 0. Попробуйте ввести следующее предложение:
10011111 11111011 AND U.
и вы увидите следующий результат:
110011011 ok
Нагляднее всего проследить, что произойдет, если поместить числа одно под другим:
10011111 11111011 AND U.
это приведет к такому результату:
10011011 ok
Второе число, 11111011, называется разрядной (битовой) маской. Разрядная маска -- это всего-навсего число, которое сравнивается с другим числом с целью изменить значение отдельных битов.
Теперь представим себе, что вы хотите снова изменить значение разряда 0 в 1. Слово AND не сможет этого сделать. Вместо него мы используем слово OR (ИЛИ). Оно также производит поразрядное сравнение двух чисел, но. если хотя бы один из разрядов установлен в " 1", то в результате тоже будет "1". Попробуем установить в "1" третий разряд в последнем примере. Для этого случая мы используем маску 00000100:
10011011 00000100 OR U.
что приводит к
10011111 Ok
т.е. к исходному числу.
Третье полезное слово XOR (исключающее ИЛИ) также производит поразрядное сравнение. Если два разряда различны, то в бите результата устанавливается "1", если одинаковы, -- то "0". Пусть вы хотите изменить значения всех разрядов числа на противоположные, т.е., например, преобразовать число 10011011 в 01100100. Попробуйте сделать так :
10011011 11111111 XOR U.
и получите
01100100 ok
Так как в маске все разряды были установлены в "1", то там, где в исходном числе была 1, в результате стал 0, а если был 0 -- стала 1.
Есть еще одно слово, NOT (HE), которое в различных версиях языка определено не очень четко. В большинстве версий, в том числе в Форт-79, слово NOT не изменяет значение битов, оно делает нечто иное, о чем мы расскажем в одной из следующих глав. Однако в Форт-83 слово NOT изменяет значение разрядов на противоположное. Таким образом,
00000000101010 NOT U.
приведет к результату
11111111010101 ok
Операция NOT не эквивалентна вычитанию каждого разряда из двоичной единицы. Сможете ли вы определить на Форт-83 слово NOT, используя XOR ? Слова AND, OR, XOR и NOT имеют и другие применения, с которыми мы познакомимся в упражнениях.