Как я учился программировать на языке С++ >> Глава 1 >> Раздел 10

Главная
Портфолио
Создание Windows приложений
Полезные ссылки
Справочник
Карта сайта
Контакты
"Я думаю, что мы получаем одну и ту же информацию,
 и, возможно, от одних и тех же людей.
"
  Н.С. Хрущев.




Среди множества языков программирования С++ занимает особое место. Он достаточно прост, лаконичен и исключительно эффективен. Язык С++ создан профессионалами для профессионалов и является расширением языка С для поддержки объектно-ориентированной парадигмы программирования.

Содержание


Главная

Часть I
Процедурное программирование в С++

Глава 1
Глава 2
Глава 3
Глава 4
Глава 5
Глава 6

Часть II
Объективно- ориентированное  программирование в С++
 
Глава 7
Глава 8
Глава 9
Глава 10
Глава 11
Глава 12






Часть I - Процедурное программирование в С++
Глава 1 - Основы языка С++
Раздел 10 - Побитовые операторы и двоичное представление чисел
Раздел 1 Раздел 2 Раздел 3 Раздел 4 Раздел 5 Раздел 6
Раздел 7 Раздел 8 Раздел 9 Раздел 10 Раздел 11 Раздел 12
Примеры решения задач к Главе 1
Резюме к Главе 1
Контрольные вопросы к Главе 1
Задачи для самостоятельного решения к Главе 1
Примечания






Раздел 10

Побитовые операторы и двоичное представление чисел

Язык программирования С++ обладает полным набором побитовых операторов. Побитовые операторы применяются при выполнении операций с битами в двоичном представлении числовых значений. Прежде чем непосредственно  рассмотреть сами операторы, кратко остановимся на концепции двоичного представления числовых значений.

Как известно, целые числа представляются в виде последовательности цифр. Такое представление чисел называется позиционным. Весь набор цифр, которые могут использоваться в позиционном представлении числа, определяют систему счисления. В повседневной жизни используется десятичная система счисления, в которой числа представлены цифрами от 0 до 9.

В программировании более популярны системы счисления с количеством цифр, равным степени двойки: восьмеричная и шестнадцатеричная. Однако двоичная система счисления - вне конкуренции. В этой системе счисления числа записываются последовательностью из двух цифр: 0 и 1.

Каждая позиция в двоичном представлении числа соответствует биту. Таким образом, с помощью бита можно записать два значения: 0 или 1. Если для представления числа используется n бит, то в этом случае существует 2n различных комбинаций, каждая из которых соответствует отдельному числу. Например, с помощью 8 бит(1 байт) можно записать 28 = 256 чисел.

При представлении двоичным кодом положительных чисел можно было бы использовать стандартное математическое представление числа в двоичной системе. Однако на практике приходится иметь дело и с отрицательными числами, причем с технической точки зрения знаком "минус" здесь не обойтись - минус можно написать на бумаге, а реализовать его в памяти компьютера намного сложнее.

Для определения знака числа используют старший бит в позиционной записи. Нулевой старший бит соответствует положительному числу, а единичный старший бит соответствует отрицательному числу. При этом перевод для положительных чисел из двоичной системы счисления в десятичную осуществляется стандартными методами: если в двоичном представлении число позиционно задается как bnbn-1...b2b1b0 (причем цифры bi могут принимать значения 0 или 1, а старший бит для положительных чисел равен 0), то в десятичной системе число вычисляется как b020 + b121 + b222 + ... + bn-12n-1 + bn2n.

С отрицательными числами дела обстоят несколько сложнее. Чтобы перевести отрицательное число с позиционным представлением в двоичной системе bnbn-1...b2b1b0 (старший бит для отрицательного числа bn = 1), необходимо проделать несложную процедуру из двух этапов.

Во-первых, производится побитовое инвертирование кода, т.е.  каждый бит в представлении числа меняется на противоположный: 0 на 1 и 1 на 0.

Во-вторых, результат переводится в десятичную систему и к нему добавляется 1. Это модуль отрицательного числа. Чтобы получить само число, модуль числа необходимо умножить на -1.

Чтобы перевести число из десятичной системы в двоичную, проделывают обратную процедуру: от модуля отрицательного числа отнимается 1, результат переводится в бинарный код, после чего проводится побитовое инвертирование.

Проиллюстрируем это не примере.

Рассмотрим 8-битовое бинарное положительное число 01001011, что в десятичной системе счисления соответствует числу 20 + 21 + 23 + 26 = 1 + 2 + 8 + 64  = 75.

Определим бинарное машинное представление для отрицательного числа -75. Отнимем от модуля числа единицу, получаем 74. Бинарное представление для этого числа 01001010 (74 = 21 + 23 + 26). После побитового инвертирования из числа 01001010 получаем 10110101. Это и есть представление числа -75.

В том, что это так, легко убедиться: сложим числа 01001010 и 10110101. Формально получаем 100000000, однако поскольку числа 8-битовые, лишний единичный старший бит отбрасывается, и получается представление 00000000, что соответствует нулю, как и должно быть.

Теперь рассмотрим основные побитовые операции и операторы, которые используются для этого в языке программирования С++. Список побитовых операторов приведен в таблице 1.6.

Таблица 1.6 Побитовые операторы С++
Оператор
Назначение
&
Побитовое И. Бинарный оператор. Результатом выражения a&b является число, каждый бит которого в двоичном представлении равен результату сравнения соответствующих битов a и b: значение равно 1, если оба сравниваемых бита равны 1. В противном случае значение бита равно 0.
|
Побитовое ИЛИ. Бинарный оператор. Результатом выражения a | b является число, каждый бит которого в двоичном представлении равен результату сравнения соответствующих битов чисел a и b: значение бита равно 1, если хотя бы один из сравниваемых битов равен 1. В противном случае значение бита равно 0.
^
Побитовое исключающее ИЛИ. Бинарный оператор. Результатом выражения a ^ b является число, каждый бит которого в двоичном представлении равен результату сравнения соответствующих битов чисел a и b: значение бита равно 1, если один и только один из сравниваемых битов равен 1. В противном случае значение бита равно 0.
~
Побитовое отрицание(дополнение до единицы). Унарный оператор. Результатом выражения ~a является число, которое получается побитовым инвертированием числа а.
>>
Сдвиг вправо. Бинарный оператор. В двоичном представлении числа, указанном слева от оператора, выполняется сдвиг всех битов вправо на число позиций, указанных справа от оператора. При этом старший бит знака остается неизменным, а выходящие за диапазон младшие биты теряются.
<<
Сдвиг влево. Бинарный оператор. В двоичном представлении числа, указанном слева от оператора, выполняется сдвиг всех битов влево на число позиций, указанных справа от оператора, с заполнением младших битов нулями и потерей старших битов.

Приведем некоторые примеры использования побитовых операторов. Они представлены в таблице 1.7. Даже в самых простых случаях результат может оказаться весьма неожиданным.

Таблица 1.7 Примеры использования побитовых операторов
Выражение
 Значение 
Пояснение
5 & 3
1
В двоичном представлении число 5 имеет вид 101, а число 3 представляется как 011. Побитовое сравнение чисел 101 и 011 с помощью побитового И & дает 001, что в десятичной системе соответствует числу 1.
5 | 3
7
Применение оператора побитового ИЛИ |  для сравнения чисел 101 и 011 дает 111, что в десятичной системе соответствует числу 7.
5 ^ 3
6
Применение оператора побитового исключающего ИЛИ ^  для сравнения чисел 101 и 011 дает 110, что в десятичной системе соответствует числу 6.
~5
-6
После применения операции побитового инвертирования ~ к числу 5 требует особых пояснений. На самом деле в 8-битовом представлении число 5 имеет вид 00000101. В предыдущих случаях нулевые старшие разряды роли не играли, поэтому они явно не указывались. При инвертировании наличие старших нулевых битов важно. Инвертирование дает 11111010. Это не что иное, как представление  в двоичном машинном коде числа -6. Последнее читатель может проверить самостоятельно.
5 >> 2
1
После сдвига вправо на две позиции для числа 5(двоичный код 101) получаем 001. В десятичной системе это число 1.
5 << 2
20
После сдвига влево на две позиции для числа 5(двоичный код 101) получаем 00100. В десятичной системе это число 20.

Обращаем внимание читателя  на особенности применения операции побитового сдвига к отрицательным числам. Например, результатом выражения -6 >> 5 является число -1. Дело в том, что в бинарном коде 11111010 для числа -6  при сдвиге вправо на 5 позиций при условии сохранения значения ставшего бита знака получаем  код 11111111. Это код числа -1.

Особенности операций в двоичной системе таковы, что сдвиг в побитовом представлении числа на одну позицию влево означает умножение этого числа на 2. Следует только помнить, что с определенного момента при сдвиге вправо теряются старшие биты.

Представим, что число задается 8 битами.

Если воспользоваться командной 1 << 6,  получим в качестве результата значение 26=64.

Действительно, десятичное число 1 в двоичной системе в 8-битовом представлении задается как 00000001. после сдвига влево на 6 позиций получаем 01000000, что в десятичной системе соответствует числу 64.

Однако если воспользоваться командой 1 << 7, получим в качестве результата  -128.

Объясняется это следующим обстоятельством

После сдвига влево на 7 позиций из числа 00000001, получаем число 10000000.

Это отрицательное число, о чем свидетельствует старший единичный бит.

Переводя это число в десятичную систему, сначала инвертируем бинарный код и получаем 01111111. Это код числа 127. Чтобы получить конечное значение, необходимо прибавить к этому результату 1 и добавить минус - в результате приходим к значению -128.






В основу сайта положена информация из книги
"Самоучитель C++ с примерами и задачами. Книга + CD", СПб, Наука и Техника, 2010. - 480с.: ил.(+CD)
2010 - 2011 Все авторские права сохранены
Hosted by uCoz