[c++] ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๊ฐœ๋…๊ณต๋ถ€ :: ๋น„ํŠธ์กฐ์ž‘ (๋น„ํŠธ๋งˆ์Šคํฌ, ์—ฐ์‚ฐ, ์ฝ”๋“œ ๊ตฌํ˜„)

๋น„ํŠธ ์กฐ์ž‘

๊ฐœ๋…

๋น„ํŠธ(bit)๋ž€ 0๊ณผ 1์˜ ๊ฐ’์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋Š” ๋ฐ์ดํ„ฐ์˜ ๋‹จ์œ„์ด๋‹ค. 4bit๋ฅผ ๋ชจ์€ ๋‹จ์œ„๋ฅผ ๋‹ˆ๋ธ”(nibble)์ด๋ผ ๋ถ€๋ฅด๊ณ , 8bit๋ฅผ ๋ชจ์€ ๋‹จ์œ„๋ฅผ ๋ฐ”์ดํŠธ(byte)๋ผ๊ณ  ๋ถ€๋ฅธ๋‹ค. 2byte๋ฅผ ๋ชจ์€ ๋‹จ์œ„๋Š” ์ผ๋ถ€ ์ „์žํ†ต์‹ ๊ธฐ๊ธฐ์—์„œ ์›Œ๋“œ(word)๋ผ๊ณ  ํ•œ๋‹ค.

 

๊ตฌํ˜„

C++์—์„œ๋Š” ๋น„ํŠธ๋ฅผ ๋‹ค๋ฃจ๊ธฐ ์œ„ํ•ด์„œ <bitset>์ด๋ผ๋Š” ํ—ค๋”๋ฅผ ํฌํ•จํ•ด์„œ ์‚ฌ์šฉํ•œ๋‹ค.

 

์—ฐ์‚ฐ

 C++์—์„œ ๋น„ํŠธ์—ฐ์‚ฐ๋“ค์€ ์œ„์—์„œ ์–ธ๊ธ‰ํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ ์‰ฝ๊ฒŒ ๊ฐ€์ ธ๋‹ค ์“ธ ์ˆ˜ ์žˆ์ง€๋งŒ, ๊ฐœ๋… ๊ณต๋ถ€ ์ธก๋ฉด์—์„œ ๊ทธ๋ƒฅ ๊ตฌํ˜„๋„ ํ•˜๊ณ  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์‚ฌ์šฉ๋ฒ•๋„ ์ตํ˜€๋‘๋ คํ•œ๋‹ค.

 

 ๋ฉ”๋ชจ๋ฆฌ ์ƒ์— ๋ณ€์ˆ˜๋ฅผ ์ €์žฅํ•˜๋Š” ๊ฒƒ์ด 1byte ๋‹จ์œ„๋กœ ๊ฐ€๋Šฅํ•˜๊ธฐ ๋•Œ๋ฌธ์—, bit ๋‹จ์œ„์˜ ์ž๋ฃŒํ˜•์€ ์—†๋‹ค. ๋‹ค๋งŒ bool ํ˜•์€ ๋ฉ”๋ชจ๋ฆฌ ์ƒ์—์„œ 1byte๋ฅผ ์ฐจ์ง€ํ•˜์ง€๋งŒ ๊ฐ€๋Šฅํ•œ ๊ฐ’์ด true ํ˜น์€ false ๋ฐ–์— ์—†์œผ๋ฏ€๋กœ ์ด๋ฅผ ์ด์šฉํ•ด์„œ 0๊ณผ 1์„ ํ‘œํ˜„ํ•˜๊ธฐ๋กœ ํ•˜์ž.

(์ž๋ฃŒํ˜• ์ •๋ฆฌ)

 

๊ธฐ๋ณธ ๊ฐœ๋…

2์˜ ๋ณด์ˆ˜, ์Œ์ˆ˜

์ปดํ“จํ„ฐ๊ฐ€ ์ •์ˆ˜๋ฅผ ์ €์žฅํ•  ๋•Œ๋Š” ๋Œ€๋ถ€๋ถ„ 2์˜ ๋ณด์ˆ˜ ํ˜•ํƒœ๋กœ ์ €์žฅํ•œ๋‹ค. ๊ทธ ์™ธ์—๋„ ๋ถ€ํ˜ธํ™” ์ ˆ๋Œ“๊ฐ’์œผ๋กœ ์ €์žฅํ•  ์ˆ˜๋„ ์žˆ๊ณ  1์˜ ๋ณด์ˆ˜ ํ˜•ํƒœ๋กœ ์ €์žฅํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

ํ‘œํ˜„๋ฐฉ์‹ +5 -5
๋ถ€ํ˜ธํ™” ์ ˆ๋Œ“๊ฐ’ 0101 1101
1์˜ ๋ณด์ˆ˜ 0101 1010
2์˜ ๋ณด์ˆ˜ 0101 1011

 

 

 ๊ฐ€์žฅ ์™ผ์ชฝ์˜ MSB(์ตœ์ƒ์œ„ ๋น„ํŠธ)๋Š” ์ˆ˜์˜ ๋ถ€ํ˜ธ๋ฅผ ๋‚˜ํƒ€๋‚ด๊ณ  MSB๋ฅผ ์ œ์™ธํ•œ ๋‚˜๋จธ์ง€ ๋น„ํŠธ๋“ค๋กœ ์ˆ˜๋ฅผ ๋‚˜ํƒ€๋‚ธ๋‹ค. MSB๊ฐ€ 0์ด๋ฉด ์–‘์ˆ˜์ด๊ณ  1์ด๋ฉด ์Œ์ˆ˜์ด๋‹ค. ๋”ฐ๋ผ์„œ n๋น„ํŠธ, 2์˜ ๋ณด์ˆ˜ ํ˜•ํƒœ๋กœ ์ •์ˆ˜๋ฅผ ๋‚˜ํƒ€๋‚ผ ๋•Œ, ์ •์ˆ˜์˜ ๋ฒ”์œ„๋Š” -2^(n-1)~2^(n-1)-1์ด๋‹ค. ๋‚˜๋จธ์ง€ ๋‘ ๋ฐฉ์‹๊ณผ๋Š” ๋‹ค๋ฅด๊ฒŒ +0์™€ -0์ด ์•„๋‹Œ ํ•˜๋‚˜์˜ 0์œผ๋กœ ํ‘œํ˜„ํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ํ‘œํ˜„ ๋ฒ”์œ„๊ฐ€ ๋” ํฌ๋‹ค.

 

 

 ์Œ์ˆ˜๋ฅผ ๋‚˜ํƒ€๋‚ด๊ธฐ ์œ„ํ•ด์„œ๋Š” ๊ธฐ์กด์˜ ์ˆ˜์—์„œ ๋น„ํŠธ๋ฅผ ๋’ค์ง‘์€ ๋‹ค์Œ(1์˜ ๋ณด์ˆ˜) 1์„ ๋”ํ•ด์ฃผ๋ฉด ๋˜๋Š”๋ฐ, ์ด๋Š” ๊ธฐ์กด์˜ ์ˆ˜๋ฅผ 2์˜ ๋ณด์ˆ˜ํ‘œํ˜„์„ ์ด์šฉํ•ด์„œ ์Œ์ˆ˜๋กœ ๋‚˜ํƒ€๋‚ธ ๊ฒƒ์ด๋‹ค. ๊ธฐ์กด์˜ ์ˆ˜์™€ ํ•ด๋‹น ์ˆ˜์˜ ๋ณด์ˆ˜๋ฅผ ํ•ฉํ•˜๋ฉด ์ง„์ˆ˜๊ฐ€ ๋‚˜์˜ค๋Š”๋ฐ, ์œ„์˜ ์˜ˆ์ œ์—์„œ๋Š” ๊ธฐ์กด์˜ ์ˆ˜๊ฐ€ 5์ด๊ณ  ๋งˆ์ง€๋ง‰ ์ˆ˜๊ฐ€ -3์œผ๋กœ ํ‘œ์‹œ๋œ ๋ฐ์—์„œ ๋ณด์ˆ˜์˜ ์„ฑ์งˆ์„ ๋งŒ์กฑํ•œ๋‹ค๊ณ  ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

 

 ์ปดํ“จํ„ฐ ๋‚ด๋ถ€์—์„œ๋Š” ์‚ฌ์น™์—ฐ์‚ฐ ์‹œ ๊ฐ€์‚ฐ๊ธฐ(Adder)๋งŒ ์ด์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ์ด๋ ‡๊ฒŒ 2์˜ ๋ณด์ˆ˜ ํ‘œํ˜„๋ฒ•์„ ์ด์šฉํ•ด์„œ ๋ง์…ˆ์„ ๊ณ„์‚ฐํ•˜๋ฉฐ ๋บ„์…ˆ๋„ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์Œ์ˆ˜๋ฅผ ๋งŒ๋“ค์–ด์„œ ๋ง์…ˆ์„ ๊ณ„์‚ฐํ•œ๋‹ค.

(์‹ค์ˆ˜ ํ‘œํ˜„)

 

์‚ฐ์ˆ  ์‹œํ”„ํŠธ, ๋…ผ๋ฆฌ ์‹œํ”„ํŠธ

 ์‹œํ”„ํŠธ ์—ฐ์‚ฐ์€ ๋น„ํŠธ๋ฅผ 1bit์”ฉ ๋ฐ€๋ฉด์„œ ์ƒ๊ธด ๋นˆ์ž๋ฆฌ์— ์ƒˆ๋กœ์šด bit๋ฅผ ์ฑ„์›Œ์ฃผ๋Š” ์—ฐ์‚ฐ์ด๋‹ค.

 

 

 ์‚ฐ์ˆ  ์‹œํ”„ํŠธ ์—ฐ์‚ฐ์€ ๋ถ€ํ˜ธ๋น„ํŠธ๋ฅผ ๊ทธ๋Œ€๋กœ ์ฑ„์›Œ์ค€๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ 2๋กœ ๋‚˜๋ˆ„๊ฑฐ๋‚˜ ๊ณฑํ•œ ๊ฒฐ๊ณผ์™€ ๊ฐ™๋‹ค๊ณ  ๋ณด๋ฉด ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์‚ฐ์ˆ  ์‹œํ”„ํŠธ ์—ฐ์‚ฐ์ด๋ผ๊ณ  ๋ถˆ๋ฆฐ๋‹ค.

 ๋…ผ๋ฆฌ ์‹œํ”„ํŠธ ์—ฐ์‚ฐ์€ ๋ถ€ํ˜ธ๋น„ํŠธ์— 0์„ ์ฑ„์›Œ์ค€๋‹ค. ๋”ฐ๋ผ์„œ ๋…ผ๋ฆฌ์ ์œผ๋กœ ๋น„ํŠธ๋ฅผ ์ œ์–ดํ•˜๋Š” ์—ฐ์‚ฐ์œผ๋กœ ์‚ฐ์ˆ ์ ์œผ๋กœ๋Š” ๊ฑฐ์˜ ๊ด€๊ณ„๊ฐ€ ์—†๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ์ˆซ์ž๊ฐ€ ๋ณ€ํ™”ํ•œ๋‹ค.

 

๊ธฐ๋ณธ ์—ฐ์‚ฐ

  • NOT [~] : 1์ด๋ฉด 0, 0์ด๋ฉด 1

  • OR [|] : ๋‘ ๊ฐ’ ์ค‘ 1์ด ํ•˜๋‚˜๋ผ๋„ ์žˆ๋‹ค๋ฉด 1, ์•„๋‹ˆ๋ฉด 0

    ํ•ฉ์ง‘ํ•ฉ ๊ฐœ๋…๊ณผ ์œ ์‚ฌํ•˜๋‹ค.

  • XOR [^] : ๋‘ ๊ฐ’์ด ๋‹ค๋ฅด๋ฉด 1, ๊ฐ™์œผ๋ฉด 0

    ์‹ค์ œ๋กœ๋Š” XOR์— ๋“ค์–ด๊ฐ€๋Š” ๊ฐ’ ์ค‘ 1์˜ ๊ฐฏ์ˆ˜๊ฐ€ ํ™€์ˆ˜๊ฐœ์ด๋ฉด 1

  • AND [&] : ๋‘ ๊ฐ’ ๋ชจ๋‘ 1์ด๋ผ๋ฉด 1, ์•„๋‹ˆ๋ฉด 0

    ๊ต์ง‘ํ•ฉ ๊ฐœ๋…๊ณผ ์œ ์‚ฌํ•˜๋‹ค.

  • SHIFT [<< >>] : ๋น„ํŠธ ๋‹จ์œ„๋กœ ํ•œ ์นธ์”ฉ ๋ฏธ๋Š” ์—ฐ์‚ฐ

 

ํ•จ์ˆ˜ ๊ตฌํ˜„

  1. Get : ํŠน์ • ์œ„์น˜์˜ ๋น„ํŠธ ๊ฐ’์„ ๊ฐ€์ ธ์˜จ๋‹ค.
  2. Set : ํŠน์ • ์œ„์น˜์˜ ๋น„ํŠธ ๊ฐ’์„ ์„ธํŒ…ํ•œ๋‹ค.
  3. Count : ์„ธํŒ…๋œ ๋น„ํŠธ ๊ฐ’์ด ๋ช‡ ๊ฐœ์ธ์ง€ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
  4. Clear : ๋น„ํŠธ๋ฅผ 0์œผ๋กœ ์ดˆ๊ธฐํ™” ํ•œ๋‹ค.
  5. Toggle : ๋น„ํŠธ๋ฅผ ๋ฐ˜์ „์‹œํ‚จ๋‹ค.
  6. MSB : ์ตœ์ƒ์œ„ ๋น„ํŠธ๋ฅผ ์ฐพ๋Š”๋‹ค.
  7. LSB : ์ตœํ•˜์œ„ ๋น„ํŠธ๋ฅผ ์ฐพ๋Š”๋‹ค.

 

<bitset> ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ด์šฉ

#include <bitset>
#include <iostream>

using namespace std;

int main() {
    bitset<5> num;
    cout << num << endl; // 00000

    // set
    num.set(2, 1);
    num[3] = 1;
    cout << num << endl; // 01100 

    // get
    // pos๋ฅผ ์•ž์—์„œ๋ถ€ํ„ฐ ์„ธ์•ผํ•จ
    cout << num[2] << endl; // 1
    cout << num.test(2) << endl; // 1

    // count
    cout << num.count() << endl; // 1์ด ๋ช‡๊ฐœ? 2
    cout << num.size() - num.count() << endl; // 0์ด ๋ช‡๊ฐœ? 3

    // clear
    num.reset(2);
    cout << num << endl; // 01000

    // toggle
    // ์—ฌ๊ธฐ์„œ๋ถ€ํ„ฐ pos๋ฅผ ๋’ค์—์„œ๋ถ€ํ„ฐ ์„ธ์•ผํ•จ
    num.flip(1); 
    cout << num << endl; // 01010
    num.flip();
    cout << num << endl; // 10101


    // MSB, LSB x
}

 

์ง์ ‘ ๊ตฌํ˜„

#include <iostream>
#include <string>
#define BITNUM 8*sizeof(char)

using namespace std;

string GetString(char num) {
    string tmp(BITNUM,'0');
    for (int i = 0; i < BITNUM; i++) {
        if ((char)((char)(num << (BITNUM - 1-i)) >> BITNUM) == 0)
            tmp[BITNUM - i - 1] = '0';
        else
            tmp[BITNUM - i - 1] = '1';
    }
    return tmp;
}

bool Get(char num, int pos) {
    char tmp = 1 << (BITNUM - pos -1);
    return (tmp & num);
}

void Set(char& num, int pos) {
    char tmp = 1 << (BITNUM - pos -1);
    num = (tmp | num);
}

int Count(char num) {
    int cnt = 0;
    for (int i = 0; i < BITNUM; i++) {
        char tmp = pow(2, i);
        if ((num & tmp) != 0)
            cnt++;
    }
    return cnt;
}

void Toggle(char& num) {
    num = ~num;
}

void Toggle(char& num, int pos) {
    char tmp = pow(2, pos);
    num ^= tmp;
}

void Clear(char& num, int pos) {
    char tmp = ~((char)pow(2, BITNUM- pos-1));
    num &= tmp;
}

bool MSB(char& num) {
    if (num >> (BITNUM - 1))
        return true;
    else
        return false;
}

bool LSB(char& num) {
    char tmp = num << (BITNUM - 1);
    tmp >> (BITNUM - 1);

    if (tmp)
        return true;
    else
        return false;
}


int main() {
    char num = 0;

    // set
    Set(num, 2); Set(num, 5); Set(num, 6);
    cout << GetString(num) << endl;// 00100110

    // get
    cout << Get(num, 2) << endl; // 1

    // count
    cout << Count(num) << endl;

    // clear
    Clear(num, 5);
    cout << GetString(num) << endl;// 00100010

    // toggle
    Toggle(num); //
    cout << GetString(num) << endl;// 11011101
    Toggle(num,1); Toggle(num, 7);
    cout << GetString(num) << endl;// 01011111

    // MSB
    cout << MSB(num) << endl; // 0
    // LSB
    cout << LSB(num) << endl; // 1

}

 

๋น„ํŠธ๋งˆ์Šคํฌ(BitMask)

์—ฌ๋Ÿฌ ํ‘œํ˜„ ์‹œ ๋น„ํŠธ๋ฅผ ์ด์šฉํ•˜์—ฌ ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ์„ ์ค„์ด๊ณ  ํšจ์œจ์ ์œผ๋กœ ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด๋ฅผ bitmask๋ผ๊ณ  ํ•˜๋Š”๋ฐ, ์˜ˆ๋ฅผ ๋“ค์–ด ์ง‘ํ•ฉ {1,2,3,5}๊ฐ€ ์žˆ์„ ๋•Œ 11101๋กœ ๋‚˜ํƒ€๋‚ผ ์ˆ˜ ์žˆ๊ณ  ์ €์žฅํ•  ๋•Œ๋Š” 10์ง„์ˆ˜๋กœ 29๋ฅผ ์ €์žฅํ•˜๋ฉด ๋œ๋‹ค. ๋”ฐ๋ผ์„œ ๋ฐฐ์—ด์„ ์ด์šฉํ•  ํ•„์š”์—†์ด ์ •์ˆ˜ ํ•˜๋‚˜๋งŒ์œผ๋กœ ์ €์žฅ์ด ๊ฐ€๋Šฅํ•˜๋ฏ€๋กœ ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ์„ ์ค„์ผ ์ˆ˜ ์žˆ๋‹ค. ๋น„ํŠธ๋งˆ์Šคํฌ๋ฅผ ๋‹ค๋ฃจ๊ธฐ ์œ„ํ•ด์„œ๋Š” ์œ„์—์„œ ์–ธ๊ธ‰ํ–ˆ๋˜ ๋น„ํŠธ์—ฐ์‚ฐ์„ ์‚ฌ์šฉํ•ด์•ผํ•œ๋‹ค.

 

์ฐธ๊ณ 

https://iamsjy17.github.io/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98_%EA%B8%B0%EC%B4%88/2019/05/09/bitop.html

๋ฐ˜์‘ํ˜•