Архитектура Аудит Военная наука Иностранные языки Медицина Металлургия Метрология
Образование Политология Производство Психология Стандартизация Технологии 


Выполнение операций AND, OR, XOR и NOT




Операции AND, OR, XOR и NOT осуществляют соответственно операторы &, |, ^ и ~. Они выполняют те же действия, что и эквивалентные им логические операторы, &&, ||, . Различие состоит в том, что побитовые операции выполняются над отдельными разрядами числа. В приведенной ниже таблице 7 показан результат выполнения каждого оператора над отдельными битами.

Таблица 1.7 – Побитовые операции

A B A&B A|B A^B ~A

Как правило, побитовая операция 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; Просмотров: 1092; Нарушение авторского права страницы


lektsia.com 2007 - 2021 год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! (0.012 с.) Главная | Обратная связь