Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Основы.doc
Скачиваний:
59
Добавлен:
07.03.2016
Размер:
3.6 Mб
Скачать

5.5. Порозрядні операції

Таблиця 5.1

Основні порозрядні операції

Операція

Значення

&

Порозрядне І

|

Порозрядне АБО

^

Порозрядне виключаюче АБО

~

Порозрядне заперечення (доповнення до 1)

Таблиця 5.2

Характеристика основних порозрядних операцій

1-й біт

Операція

2-й біт

Результат

1

&

1

1

1

&

0

0

0

&

1

0

0

&

0

0

1

|

1

1

1

|

0

1

0

|

1

1

0

|

0

0

1

^

1

0

1

^

0

1

0

^

1

1

0

^

0

0

~

1

0

~

0

1

9 & 14 // 8

1 0 0 1

1 1 1 0

1 0 0 0

9 | 14 // 15

1 0 0 1

1 1 1 0

1 1 1 1

9 ^ 14 // 7

1 0 0 1

1 1 1 0

0 1 1 1

~ 9 // 6

1 0 0 1

0 1 1 0

Приклад роботи з оператором порозрядного заперечення ~.

#include <iostream>

using namespace std;

void main()

{

unsigned char u1 = ~9; // 246

signed char u2 = ~9; // -10

unsigned int u3 = ~9; // 65526

signed int u4 = ~9; // -10

unsigned long u5 = ~9; // 4294967286

signed long u6 = ~9; // -10

cout<<"u1 = "<<(int)u1<<"\n";

cout<<"u2 = "<<(int)u2<<"\n";

cout<<"u3 = "<<u3<<"\n";

cout<<"u4 = "<<u4<<"\n";

cout<<"u5 = "<<u5<<"\n";

cout<<"u6 = "<<u6<<"\n";

}

Приклад визначення парного або непарного значення

#include <iostream>

using namespace std;

void main()

{

int input;

cin>> input;

if(input & 1) // Істина, якщо число непарне

cout<< "Число непарне";

else

cout<< "Число парне";

}

У ASCII кодах єдина відзнака між маленькими і великими буквами значення 0 або 1 у 5-му біті - для англійських букв.

Біт → 7 6 5 4 3 2 1 0

А → 0 1 0 0 0 0 0 1 → Шест. 41, Дес. 65

a → 0 1 1 0 0 0 0 1 → Шест. 61, Дес. 97

Щоб перетворити символ до верхнього регістру необхідно встановити 0 у 5-й біт.

Для цієї мети можна використовувати маску зі значенням

32(10) = 20(16) = 1 0 0 0 0 0(2) → бітова маска.

Наведемо приклад переключення між маленькими та великими буквами, використовуючи порозрядні операції.

Приклад:

#include <iostream>

using namespace std;

#define bitmas (0x20) // 100000

void main()

{

char a,b,c;

cin>>a; //g

cin>>b; //M

cin>>c; //p

//Виключення 5-го біту (0) (великі букви)

a = a & ~bitmas;

b &= ~bitmas; // Складові порозрядні

c &= ~bitmas; // операції

cout<<a<<b<<c<<"\n"; //GMP

//Включення 5-го біту (1) (маленькі букви)

a = a | bitmas;

b |= bitmas; // Складові порозрядні

c |= bitmas; // операції

cout<<a<<b<<c<<"\n"; //gmp

//Переключення 5-го біту

a = a ^ bitmas;

b ^= bitmas; // Складові порозрядні

c ^= bitmas; // операції

cout<<a<<b<<c<<"\n"; //gmp

}

Для переключення 5-го біта з 1 у 0 (виключення 5-го біту) використовується порозрядний оператор І (“&”) разом з оператором порозрядного заперечення (“~”). У випадку переключення 5-го біту з 0 у 1 (включення 5-го біту) використовується порозрядний оператор АБО (“|”). Для переключення заданого біта з 0 у 1 і навпаки, ефективно використовувати виключаюче АБО (“^”).

У даному прикладі спочатку виключається 5-й біт (перетворюється у 0) та в результаті отримаємо три маленькі букви “gmp”. Потім 5-й біт включається (перетворюється у 1) – отримуємо три великі букви “GMP”. На останньому етапі переключаємо отриманий результат, використовуючи виключаюче АБО (“^”) (1 перетворюється у 0) та отримуємо знову три маленькі букви “gmp”.

У операційній системі Windows використовуються порозрядні операції для додавання або виключення атрибутів вікна.

Оператор “виключаючи АБО (^)” використовується у двовимірній графіці GDI при роботі з піксельними операціями, а також в сучасних криптографічних алгоритмах.

Порозрядні операції зсуву.

Синтаксис:

a << b → зсув ліворуч

a >> b → зсув праворуч

Приклад:

29 << 3 // 232

0 0 0 1 1 1 0 1 // 29

1 1 1 0 1 0 0 0 // 232

← зсув на 3

Ця операція дорівнює 29∙23 = 232

Початковий знак від’ємного числа зберігається. Порозрядний зсув для від’ємного числа робиться наступним чином. При зсуві числа ліворуч “<<” від’ємний знак числа зберігається, а в кінці додаються нулі. При зсуві від’ємного числа праворуч старші розряди заміняються одиницею, а не нулем.

Розпишемо арифметику порозрядного зсуву для додатних та від’ємних чисел.

Якщо x додатне число, тоді

x << n = x * 2n

x >> n = x / 2n (цілочисельне ділення)

Якщо x від’ємне число, тоді

x << n = – (|x| * 2n)

x >> n = – (|x| / 2n) – 1 (|x| / 2n – цілочисельне ділення)

Приклад порозрядних зсувів.

#include <iostream>

using namespace std;

void main()

{

int num_1 = 25; // 0000000000011001

int num_2 = -25; // 1111111111100111

int shift_1, shift_2, shift_3, shift_4;

shift_1 = num_1 << 3; // 0000000011001000 200

shift_2 = num_1 >> 3; // 0000000000000011 3

shift_3 = num_2 << 3; // 1111111100111000 -200

shift_4 = num_2 >> 3; // 1111111111111100 -4

cout << shift_1 << "\t" << shift_2 << "\n";

cout << shift_3 << "\t" << shift_4 << "\n";

// 200 3

// -200 -4

}

Може бути використана складова операція порозрядного зсуву:

<<= – складений порозрядний зсув ліворуч

>>= – складений порозрядний зсув праворуч

signed int num1 = 15;

unsigned int num2 = 15;

num1 <<= 4; //множення на 16 (240)

num2 >>= 3; //ділення на 8 (1)