|
Главная » 2010 » Февраль » 11 » Операторы работы с битами
00:00 Операторы работы с битами |
Операторы работы с битами По прочтении предыдущего раздела может возникнуть вопрос, для чего вообще существуют операторы & и |. Ответ заключается в том, что эти операторы могут использоваться для выполнения операций над численными значениями. Фактиче- ски они имеют дело с хранящейся в переменной последовательностью битов, а не со значением переменной как таковым. Давайте шаг за шагом рассмотрим работу этих операторов, начав с оператора &. Он действует сле- дующим образом: каждый бит первого операнда сравнивается с находящимся в такой же позиции битом второго операнда, а бит, записывающийся в аналогичной позиции результата, определяется следующим образом (см. табл. слева). Аналогичные действия выпол- няются и в случае применения оператора |, только результат вычисляется несколько иначе (см. табл. справа). В качестве примера рассмот- рим операцию, выполняемую следующим кодом: int result, opl, op2; . opl = 4 ; ор2 = 5; result = opl &. op2; Здесь необходимо принять во внимание двоичное представление операндов opl и ор2, соответственно 100 и 101. Результат этой операции получается лутем срав- нения двоичных битов, находящихся в одинаковых позициях в каждом из этих ло- гических представлений: Бит операнда 1 1 1 0 0 Бит операнда 2 1 0 1 0 Бит результата выполнения операции & 1 0 0 0 Бит операнда 1 1 1 0 0 Бит операнда 2 1 0 1 0 Бит результата выполнения операции | 1 1 1 0 Управление порядком выполнения 51 & О О 1 О О • Первому слева биту результата присваивается значение 1, если оба крайних левых бита opi и ор2 равны 1, и значение 0 в противном случае. • Следующему биту результата присваивается значение 1, если оба следующих бита opi и ор2 равны 1, и значение 0 в противном случае. • Так продолжается для всех остальных битов. В данном примере крайние биты слева у обоих операндов opi и ор2 равны 1, поэтому крайний левый бит результата также будет равен 1. В следующей позиции оба бита равны 0, а в третьей позиции биты равны соответственно 1 и 0; таким образом, второй и третий биты результата будут равны 0. В качестве окончатель- ного результата в двоичном представлении будет получено число 100, т. е. резуль- тат выполнения этой операции будет равен 4. Все вышесказанное можно проиллюстрировать следующим образом (см. рис. слева). Аналогичный процесс происходит при ис- пользовании оператора |, с тем лишь отличием, что получающийся в результате бит равняет- JL_ 4 5 0 0 I ся 1 в том случае, если хотя бы один из соответствую- 1 0 1 щих битов операндов равен 1 (см. рис. справа). Точно таким же способом можно использовать и оператор ". В этом случае в результате появляется 1, если только у одного из операндов, но не у обоих од- новременно, в соответствующей позиции находится единица (см. табл. слева). В языке С# допускается использование унарного оператора работы с битами ~, воздействие которого на операнд состоит в инвертировании (изменении) Бит операнда 1 1 1 0 0 Бит операнда 2 1 0 1 0 Бит результата выполнения операции Л 0 1 1 0 всех его битов таким образом, что все биты, ко- торые были равны 0, получают значение 1, и на- оборот (см. табл. справа). Такие побитовые операции оказываются весь- ма полезными в самых разных ситуациях, посколь- ку они предлагают простой метод использования Бит операнда Бит результата выполнения операции Г 1 0 Биты 000 100 010 001 101 но он 111 Десятичное представление 0 4 2 1 5 6 3 7 Значение Черный Красный Зеленый Синий Пурпурный Желтый Голубой Белый отдельных битов переменной для хранения информации. Рассмотрим простое представление цвета, в котором ис- пользуется три бита для указания наличия красной, зеле- ной и синей составляющих. У нас появляется возможность задавать каждый из этих битов независимо и изменить цвет, определяемый всеми тремя битами, на один из сле- дующих вариантов (см. табл. слева). Предположим, что мы храним эти значения в перемен- ной типа int. Начиная с черного цвета или, что то же са- мое, со значения переменной типа int, равного 0, можно выполнить различные операции. Например: 52 Глава 4 bool containsRed; IttyColor = myColor I 2; :,. // Добавлен бит зеленого цвета, значение переменной myColor стало 010 111 rayColor » m y C o l o r 1 4 ; // Добавлен бит красного цвета, значение переменной щуСоlor стало 110 containsRed = (rayColor & 4) == 4; . // Выполняется проверка на наличие бита, отвечающего за красный цвет В результате выполнения последней строки кода значение переменной containsRed будет true, поскольку "красный" бит в переменной myColor равен 1. Этот способ может оказаться весьма полезным в том случае, если выполняемые операции используются для одновременной проверки нескольких битов (например, дая 32 в случае значений типа int). Однако существуют более эффективные спо- собы хранения дополнительной информации в отдельных переменных, для чего используются переменные сложных типов. Их обсуждению посвящена следующая глава. Помимо описанных выше четырех операторов для работы с битами следует рассмотреть еще два оператора. А именно: Оператор Тип Пример выражения Результат » Бинарный varl = var2 » var3; Переменной varl присваивается значение, которое получается при сдвиге двоичного содержимого переменной var2 вправо на число битов, равное значению переменной var3 « Бинарный varl = var2 « var3; Переменной varl присваивается значение, которое получается при сдвиге двоичного содержимого переменной var2 влево на число битов, равное значению переменной var3 Работу этих операторов, обычно называемых операторами побитового сдвига, лучше всего проиллюстрировать с помощью небольшого примера: int varl, var2 = 10, var3 = 2; varl = var2 « var3; В этом примере переменной varl будет присвоено значение 40. Действительно, двоичное представление числа 10 — "1010"; после сдвига на две позиции влево оно превратится в "101000" — двоичное представление числа 40. То, что мы сде- лали, можно изобразить как операцию умножения. Каждый бит при сдвиге на одну позицию влево увеличивает свое значение в два раза, соответственно сдвиг на две позиции эквивалентен умножению на 4. И наоборот, при сдвиге всех битов вправо возникает эффект деления операнда на два, при этом любой целый остаток теряется: int varl, var2 = 1 0 ; Ш-;' varl = var2 » 1; ; ••••-. ;• - В данном случае varl будет содержать значение 5, а в результате выполнения следующего примера ее значение станет равным 2: v a r l = var2 » 2; \ • •:' Управление порядком выполнения 53 Представляется маловероятным, что вам придется активно польфваться этими операторами, однако знать об их существовании полезно. Их применяют главным образом для получения предельно оптимизированного кода, когда использование других математических операций из-за их большей затратности оказывается не- приемлемым. По этой причине рассмотренные здесь операции часто задействуют, например, в драйверах устройств или системных кодах.
|
Категория: информатика |
Просмотров: 1047 |
Добавил: basic
| Рейтинг: 0.0/0 |
|
Статистика
Онлайн всего: 1 Гостей: 1 Пользователей: 0
|