Архитектура Аудит Военная наука Иностранные языки Медицина Металлургия Метрология Образование Политология Производство Психология Стандартизация Технологии |
Выполнение операций AND, OR, XOR и NOT
Операции AND, OR, XOR и NOT осуществляют соответственно операторы &, |, ^ и ~. Они выполняют те же действия, что и эквивалентные им логические операторы, & &, ||, . Различие состоит в том, что побитовые операции выполняются над отдельными разрядами числа. В приведенной ниже таблице 7 показан результат выполнения каждого оператора над отдельными битами. Таблица 1.7 – Побитовые операции
Как правило, побитовая операция AND используется для сброса отдельных разрядов. Любой бит, значение которого равно нулю, хотя бы в одном из двух операндов будет равен нулю и в результирующем значении. Например: 1 1 0 1 0 0 1 1 & 1 0 1 0 1 0 1 0 ____________ 1 0 0 0 0 0 1 0 Использование оператора &. В Unicode и ASCII коды букв нижнего Регистра отличаются от кодов букв верхнего регистра на 32. Таким образом, Для того, чтобы преобразовать символы нижнего регистра в верхний регистр, достаточно сбросить шестой бит. Поскольку на символьный тип данных отводится 16 бит, то нужно в 16-битов числе в двоичном представлении сбросить 6-й бит. Для этого нужно число 1111111111011111 преобразовать в 10-ю систему счисления (65503) и использовать в операции AND. Напишем программу перевода буквы нижнего регистра в верхний регистр путем сброса шестого бита кода символа. Листинг 1.6 //Перевод букв в верхний регистр class UpCase { public static void main(String[] args) { char ch; for (int i = 0; i < 10; i++) { ch = (char) ('a' + i); System.out.print(ch); //Данное выражение сбрасывает шестой бит ch = (char) ((int) ch& 65503); // Теперь в ch содержится // код символа верхнего // регистра System.out.print(ch + " " ); } } } Оператор AND удобен также в том случае, когда вам надо определить, установлен ли или сброшен некоторый бит числа. Например, приведенное ниже выражение определяет, установлен ли четвертый бит в переменной status. if(status & 8) System.out.println(" bit 4 is on" ); В данном случае число 8 использовано потому, что в его двоичном представлении (1000) установлен только четвертый бит. Таким образом, в выражении if значение true будет получено только тогда, когда четвертый бит значения, содержащегося в переменной status, также установлен. Подобный подход можно применить для преобразования значения типа byte в двоичный формат. Листинг 1.7 importjava.util.Scanner; //Отображение битов в составе байта publicclassShowBits { public static void main(String[] args) { byte val = 0; Scanner sc = new Scanner(System.in); System.out.println(" Введите число типа byte: 12 " ); if (sc.hasNextByte()) { val = sc.nextByte(); } for (int t = 128; t > 0; t = t / 2) { if ((val & t)! = 0) { System.out.print(" 1 " ); } else { System.out.print(" 0 " ); } } } } В цикле for последовательно проверяется каждый бит переменной val; для чтобы определить, установлен ли бит, используется операция AND. Если бит установлен, отображается цифра 1, в противном случае выводится цифра 0. Побитовая операция OR выполняет действия, противоположные операции AND и используется для установки битов. Любой бит, значение которого равно хотя бы в одном из двух операндов, будет равен единице и в результирующем значении. Оператор OR можно использовать для преобразования символов верхнего регистра в нижний регистр. Задание: Напишите программу для преобразования символов верхнего регистра в нижний регистр.
Операция XOR дает результат, в котором конкретный бит установлен в том и только в том случае, когда соответствующие биты в двух операндах имеют разные значения. Ниже приведен пример выполнения операции XOR. Операция XOR имеет одну интересную особенность, которая позволяет очень просто кодировать сообщения. Если выполнить данную операцию над некоторыми числами X и Y, a затем снова выполнить операцию XOR над результирующим, значением и числом Y, то мы снова получим число X. Таким образом, при выполнении приведенных ниже двух команд R2 получит то же значение, которое имеет x R1 = X ^ Y; R2 = R1 ^ Y; Данную особенность можно использовать для создания простейшей шифрующей программы, в которой некоторое целое число будет выполнять роль ключа, применяемого как при шифровании, так и дешифровке. Над всеми символами сообщения и данным числом будет выполняться операция XOR. В первый раз данная операция будет применена при шифровании, генерируя кодированный текст. Для декодирования операция XOR выполняется во второй раз, и результатом является исходный текст. Ниже приведен код простой программы, выполняющей шифрование и дешифровку коротких сообщений. Листинг 1.8 // Использование операции XOR для шифрования и дешифровки сообщений class Encode { class Encode { public static void main(String args[]) { String msg = " This is a test"; String encmsg = " "; String decmsg = " "; int key = 88; System.out.print(" Original message: " ); System.out.println(msg); // Кодирование сообщения for (int i = 0; i < msg.length(); i++) { encmsg = encmsg + (char) (msg.charAt(i) ^ key); } System.out.print(" Encoded message: " ); System.out.println(encmsg); // Декодирование сообщения for (int i = 0; i < msg.length(); i++) { decmsg = decmsg + (char) (encmsg.charAt(i) ^ key); } System.out.print(" Decoded message: " ); System.out.println(decmsg); } } Как видите, результат применения двух операций XOR с использованием одного и того же ключа дает в результате декодированное сообщение, совпадающее с исходным. Операция дополнения (NOT) инвертирует все биты операнда. Например, если некоторая целочисленная переменная А содержит значение, двоичное представление которого равно 10010110, результатом выполнения выражения ~A будет набор битов 01101001. Операторы сдвига В языке Java предусмотрена возможность сдвига битов, составляющих число влево или вправо на заданное количество позиций. Программисту доступны перечисленных ниже оператора сдвига. Таблица 1.8 – Операторы сдвига
Формат записи этих операторов приведен ниже. значение < < число_позиций значение > > число_позиций значение > > > число_позиций Здесь слева от оператора задается значение, подлежащее сдвигу, а справа – число позиций, на которые производится сдвиг. При сдвиге влево освободившиеся младшие биты заполняются нулями. При сдвиге вправо все происходит несколько сложнее. Как вы знаете, признаком отрицательного целого числа является единица в старшем бите, поэтому при обычном сдвиге вправо старший (знаковый) разряд дублируется. Если число положительное, то в него записывается нуль, если отрицательное – единица. Помимо сохранения знакового разряда, необходимо помнить еще об одной особенности. Отрицательные числа в языке Java (как, впрочем, и в других языках) представляются как дополнение до двух. Чтобы преобразовать положительное число в отрицательное, его надо инвертировать, а к полученному значению прибавить единицу. Таким образом, значение -1 представляется двоичной последовательностью 11111111. Сдвинув это значение вправо на любое число позиций, мы снова получим -1! Если вы не хотите, чтобы при сдвиге вправо сохранялся знаковый разряд, можете использовать беззнаковый сдвиг вправо (оператор > > > ), при этом освободившиеся старшие разряды всегда будут заполняться нулями. Беззнаковый сдвиг удобно использовать для обработки значений, не являющихся числами, например кодов состояния. При любом сдвиге биты теряются. Циклический сдвиг в языке Java не поддерживается, и нет возможности восстановить потерянные разряды. Ниже приведен код программы, которая демонстрирует эффект от использования операторов сдвига. Целочисленное значение 1 представляется набором битов, в которых лишь младший равен 1. К этому значению восемь раз применяется операция сдвига влево. После каждого сдвига на экран выводится восемь младших разрядов числа. Затем единица устанавливается в восьмой позиции и производятся сдвиги вправо. Выполняя сдвиг над значениями byte и short, необходимо соблюдать осторожность, поскольку исполняющая система Java автоматически преобразует в тип int, а лишь затем выполняет необходимые вычисления. Например, вы сдвинете вправо значение типа byte, то оно будет сначала преобразовано в int. Результат сдвига будет также иметь тип int. Обычно такое преобразование не влечет за собой никаких последствий. Однако если вы попытаетесь сдвинуть отрицательное значение, то при преобразовании в тип int старшие биты будут заполнены единицами. Это оправдано при обычном сдвиге вправо, но при беззнаковом сдвиге в старшем разряде будет обнаружена неожиданная единица. Лишь после двадцати четырех сдвигов появятся нулевые значения. Варианты записи побитовых операций Для всех побитовых операций предусмотрена сокращенная запись, подобная сокращенной записи логических и арифметических операций. Например, приведенные ниже две строки кода эквиваленты. В каждой из них выполняется операция XOR над значением переменной x и числом 127. x = x ^ 127; x ^= 127; Задачи 1. В переменной n хранится двузначное число. Создайте программу, вычисляющую и выводящую на экран сумму цифр n. 2. В переменной n хранится трёхзначное число. Создайте программу, вычисляющую и выводящую на экран сумму цифр n. 3. В переменной n хранится вещественное число с ненулевой дробной частью. Создайте программу, округляющую число n до ближайшего целого и выводящую результат на экран. 4. В переменных q и w хранятся два натуральных числа. Создайте программу, выводящую на экран результат деления q на w с остатком. Пример вывода программы (для случая, когда в q хранится 21, а в w хранится 8): 21/8=2и5востатке
Популярное:
|
Последнее изменение этой страницы: 2016-05-30; Просмотров: 1463; Нарушение авторского права страницы