86 / 90

C++ Bitwise Operators

C++ bitli operatorlar

C++ da bitli operatorlar individual bit darajasida butun sonli ma’lumotlar bilan operatsiyalarni bajaradilar. Ushbu operatsiyalar haqiqiy bitlarni sinash, sozlash yoki o'zgartirishni o'z ichiga oladi. Masalan,

example.cpp
a & b;
a | b;

Bu yerda C++ tiliga kiritilgan 6 bitli operatorlar ro‘yxati keltirilgan.

Operator Description & Bitwise AND Operator | Bitwise OR Operator ^ Bitwise XOR Operator ~ Bitwise Complement Operator << Bitwise Shift Left Operator >> Bitwise Shift Right Operator

Bu operatorlar zarur, chunki kompyuterning markaziy protsessorida mavjud arifmetik-mantiq birligi (ALU) bit darajasida arifmetik amallarni bajaradi.

[!NOTE] Bitwise operators can only be used alongside char and int data types.

1. C++ Bitwise AND Operator

Bit bo'yicha AND & operatori ikkala operand 1 bo'lsa, 1 ni qaytaradi. Aks holda, u 0 ni qaytaradi.

Quyidagi jadvalda bitli AND operatorining ishlashi ko'rsatilgan. a va b faqat ikkilik qiymatlarni, ya'ni 1 va 0 ni qabul qila oladigan ikkita operand bo'lsin.

a b a & b 0 0 0 0 1 0 1 0 0 1 1 1

[!NOTE] Yuqoridagi jadval bitli AND operatori uchun "Haqiqat jadvali" sifatida tanilgan.

Keling, 12 va 25 ikkita butun sonning bit bo'yicha AND ishini ko'rib chiqaylik:

example.cpp
12 = 00001100 (In Binary)

25 = 00011001 (In Binary)

// Bit yo'nalishi bo'yicha VA 12 va 25 ning ishlashi

     00001100
&    00011001
     _________
     00001000  = 8 (In decimal)

1-misol: Bitli VA

example.cpp
#include <iostream>
using namespace std;

int main() {
    // o'zgaruvchilarni e'lon qilish
    int a = 12, b = 25;

    cout << "a = " << a << endl;
    cout << "b = " << b << endl;
    cout << "a & b = " << (a & b) << endl;

    return 0;
}

Chiqish

kod
a = 12
b = 25
a & b = 8

Yuqoridagi misolda biz ikkita o'zgaruvchini a va b e'lon qildik. Mana, chiziqqa e'tibor bering,

example.cpp
cout << "a & b = " << (a & b) << endl;

Bu erda biz a va b o'zgaruvchilari orasida bit bo'yicha VA ni bajaramiz.

2. C++ Bitwise OR operatori

Bit bo'yicha OR | operatori operandlardan kamida bittasi 1 bo'lsa, 1 ni qaytaradi. Aks holda, u 0 ni qaytaradi.

Quyidagi haqiqat jadvali bitli OR operatorining ishlashini ko'rsatadi. a va b faqat ikkilik qiymatlarni, ya'ni 1 yoki 0 ni qabul qila oladigan ikkita operand bo'lsin.

a b a | b 0 0 0 0 1 1 1 0 1 1 1 1

Ikkita butun 12 va 25 sonlarning bit boʻyicha OR ishini koʻrib chiqamiz:

example.cpp
12 = 00001100 (In Binary)
25 = 00011001 (In Binary)

Bitwise OR Operation of 12 and 25
    00001100
|   00011001
    _________
    00011101  = 29 (In decimal)

2-misol: Bitli OR

example.cpp
#include <iostream>

using namespace std;

int main() {
    int a = 12, b = 25;

    cout << "a = " << a << endl;
    cout << "b = " << b << endl;
    cout << "a | b = " << (a | b) << endl;

    return 0;
}

Chiqish

kod
a = 12
b = 25
a | b = 29

a = 12 va b = 25 ning bit yoʻnalishi boʻyicha OR koʻrsatkichlari 29 ni beradi.

3. C++ Bitwise XOR operatori

Bit bo'yicha XOR ^ operatori operandlardan biri 1 bo'lsa, 1 ni qaytaradi. Biroq, agar ikkala operand ham 0 bo'lsa yoki ikkalasi ham 1 bo'lsa, natija 0 bo'ladi.

Quyidagi haqiqat jadvali bitli XOR operatorining ishlashini ko'rsatadi. a va b faqat ikkilik qiymatlarni, ya'ni 1 yoki 0 ni qabul qila oladigan ikkita operand bo'lsin.

a b a ^ b 0 0 0 0 1 1 1 0 1 1 1 0

Ikkita butun 12 va 25 sonlarning bit boʻyicha XOR ishini koʻrib chiqamiz:

example.cpp
12 = 00001100 (In Binary)
25 = 00011001 (In Binary)

Bitwise XOR Operation of 12 and 25
    00001100
^   00011001
    _________
    00010101  = 21 (In decimal)

3-misol: Bitli XOR

example.cpp
#include <iostream>

using namespace std;

int main() {
    int a = 12, b = 25;

    cout << "a = " << a << endl;
    cout << "b = " << b << endl;
    cout << "a ^ b = " << (a ^ b) << endl;

    return 0;
}

Chiqish

kod
a = 12
b = 25
a ^ b = 21

a = 12 va b = 25 ning bitli XOR ko‘rsatkichlari 21 ni beradi.

4. C++ bitli komplement operatori

Bit bo'yicha to'ldiruvchi operator - unar operator (faqat bitta operandda ishlaydi). Ikkilik raqamlarni 1 dan 0 ga va 0 ni 1 ga o'zgartiruvchi ~ bilan belgilanadi.

Bitwise Complement

Bitwise Complement operation in C++

Shuni ta'kidlash kerakki, har qanday N butun sonning bit bo'yicha to'ldiruvchisi -(N + 1) ga teng. Masalan,

Butun sonni ko'rib chiqing 35. Qoidaga ko'ra, 35 ning bit bo'yicha to'ldiruvchisi -(35 + 1) = -36 bo'lishi kerak. Keling, to'g'ri javobni olamizmi yoki yo'qmi, bilib olaylik.

example.cpp
35 = 00100011 (In Binary)

// Bit bo'yicha to'ldiruvchi operatordan foydalanish
~ 00100011 
 __________
  11011100

Yuqoridagi misolda biz 00100011 (35) ning bit bo'yicha to'ldiruvchisi 11011100 ekanligini olamiz. Bu erda natijani o'nli kasrga aylantirsak, biz 220 ni olamiz.

Ammo shuni ta'kidlash kerakki, biz natijani to'g'ridan-to'g'ri kasrga aylantira olmaymiz va kerakli natijani olamiz. Buning sababi shundaki, 11011100 ikkilik natija ham -36 ga teng.

Buni tushunish uchun birinchi navbatda -36 ning ikkilik chiqishini hisoblashimiz kerak. Manfiy butun sonlarning ikkilik sonini hisoblash uchun 2 ning to‘ldiruvchisidan foydalanamiz.

2-to‘ldiruvchi

N sonining 2 ning toʻldiruvchisi -N ni beradi.

Ikkilik arifmetikada 1 ning to'ldiruvchisi 0 dan 1 ga va 1 dan 0 ga o'zgaradi.

Va agar 1 ning to'ldiruvchisi natijasiga 1 ni qo'shsak, biz asl sonning 2 to'ldiruvchisini olamiz.

Masalan,

example.cpp
36 = 00100100 (In Binary)

1's Complement = 11011011 

2's Complement :   
11011011
 +     1
_________
11011100

Bu yerda biz 2 ning 36 ning toʻldiruvchisi (yaʼni -36) 11011100 ekanligini koʻrishimiz mumkin. Bu qiymat biz oldingi boʻlimda hisoblagan 35 bit boʻyicha toʻldiruvchiga teng.

Demak, 35 = -36 ning bit boʻyicha toʻldiruvchisi, deyishimiz mumkin.

4-misol: Bitli to‘ldiruvchi

example.cpp
#include <iostream>

using namespace std;

int main() {
    int num1 = 35;
    int num2 = -150;
    cout << "~(" << num1 << ") = " << (~num1) << endl;
    cout << "~(" << num2 << ") = " << (~num2) << endl;

    return 0;
}

Chiqish

kod
~(35) = -36
~(-150) = 149

Yuqoridagi misolda biz ikkita tamsayı o'zgaruvchilari num1 va num2 e'lon qildik va ularni mos ravishda 35 va -150 qiymatlari bilan ishga tushirdik.

Keyin biz ularning bitli komplementini mos ravishda (~num1) va (~num2) kodlari bilan hisoblab chiqdik va ularni ekranda ko'rsatdik.

example.cpp
The bitwise complement of 35 = - (35 + 1) = -36
i.e. ~35 = -36

The bitwise complement of -150 = - (-150 + 1) = - (-149) = 149
i.e. ~(-150) = 149

Bu biz chiqishda aniq bo'lgan narsadir.

C++ Shift operatorlari

C++ dasturlashda ikkita siljish operatori mavjud:

  • Right shift operator >>
  • Left shift operator <<

5. C++ o'ngga siljish operatori

O'ngga siljish operatori barcha bitlarni ma'lum miqdordagi belgilangan bitlar bilan o'ngga siljitadi. U >> bilan belgilanadi.

Har qanday raqamni o'ngga siljitganimizda, eng muhim bitlar o'chiriladi, eng muhim bitlar esa nolga almashtiriladi.

One bit Right Shift

One bit Right Shift Operator

Yuqoridagi rasmdan ko'rib turganimizdek, bizda 4 bitli raqam mavjud. Unda bir bitli o'ngga siljish amalini bajarganimizda, har bir alohida bit o'ngga 1 bitga siljiydi.

Natijada, eng o'ngdagi bit o'chiriladi, chapdagi bit esa bo'sh qoladi. Bu vakansiya 0 bilan almashtiriladi.

6. C++ chapga siljish operatori

Chapga siljish operatori barcha bitlarni ma'lum miqdordagi belgilangan bitlar bilan chapga siljitadi. U << bilan belgilanadi.

One bit Left Shift

One bit left shift Operator

Yuqoridagi rasmdan ko'rib turganimizdek, bizda 4 bitli raqam mavjud. Unda 1 bit chapga siljish amalini bajarganimizda, har bir alohida bit 1 bitga chapga siljiydi.

Natijada, eng chapdagi bit tashlanadi, o'ngdagi bit esa bo'sh qoladi. Bu vakansiya 0 bilan almashtiriladi.

5-misol: Shift operatorlari

example.cpp
#include <iostream>

using namespace std;

int main() {

    // ikkita butun o'zgaruvchini e'lon qilish
    int num = 212, i;

    // O'ngga siljitish operatsiyasi
    cout << "Shift Right:" << endl;

    // Raqamni 0 bitdan 3 bitga o'ngga siljitish uchun for siklidan foydalanish
    for (i = 0; i < 4; i++) {
        cout << "212 >> " << i << " = " << (212 >> i) << endl;
    }

    // Chapga siljitish operatsiyasi
    cout << "\nShift Left:" << endl;

    // Chap sonni 0 bitdan 3 bitga o'tkazish uchun for siklidan foydalanish
    for (i = 0; i < 4; i++) {
        cout << "212 << " << i << " = " << (212 << i) << endl;
    }

    return 0;
}

Chiqish

kod
Shift Right:
212 >> 0 = 212
212 >> 1 = 106
212 >> 2 = 53
212 >> 3 = 26

Shift Left:
212 << 0 = 212
212 << 1 = 424
212 << 2 = 848
212 << 3 = 1696

Yuqoridagi dasturning natijasidan shuni xulosa qilishimiz mumkinki, har qanday N soni uchun o'ngga siljish operatorining natijalari quyidagicha:

example.cpp
N >> 0 = N
N >> 1 = (N >> 0) / 2
N >> 2 = (N >> 1) / 2
N >> 3 = (N >> 2) / 2

va hokazo.

Xuddi shunday, chapga siljish operatorining natijalari:

example.cpp
N << 0 = N
N << 1 = (N << 0) * 2
N << 2 = (N << 1) * 2
N << 3 = (N << 2) * 2

va hokazo.

Shunday qilib, biz xulosa qilishimiz mumkin,

example.cpp
N >> m = [ N >> (m-1) ] / 2
N << m = [ N << (m-1) ] * 2

Haqiqiy amaliyotda bitli siljish

Yuqoridagi misolda, int ma'lumotlar turi raqamlarni 32 bitda saqlashiga e'tibor bering, ya'ni int qiymati 32 ikkilik raqam bilan ifodalanadi.

Biroq, bit bo'yicha siljish operatorlari uchun bizning tushuntirishimiz 4-bitda ifodalangan raqamlardan foydalangan.

Masalan, 13 ta asosiy 10 raqami 4-bit va 32-bitlarda quyidagicha ifodalanishi mumkin:

example.cpp
4-bit Representation of 13 = 1101
32-bit Representation of 13 = 00000000 00000000 00000000 00001101

Natijada, 13 (va har qanday boshqa raqam) uchun bit bo'yicha chapga siljish jarayoni ular ifodalangan bitlar soniga qarab farq qilishi mumkin.

Chunki 32-bitli taqdimotda 4-bitli tasvirga nisbatan chapga siljitilishi mumkin bo'lgan ko'proq bitlar mavjud.