인삿말
안녕하세요 알다브입니다.
저번 시간에 연산자에 대해서
알아봤습니다.
사실 저번 시간에 비트 연산자까지
다 끝내려했는데
비트 연산자까지 다루면
너무 길어질까봐
이번 글에서 따로 다루려 합니다.
이전 글에 연산자 표가있으니
참조해서 보길 바랄게요.
2020/05/13 - [프로그래밍언어/c언어] - C언어 독학 #6. 연산자
비트 체계
컴퓨터는 이진수로 값을 저장하고 처리합니다.
이진수는 0과 1로 이루어진 수의 체계를
말합니다.
그럼 이러한 이진수를 사용하는 이유는
무엇일까요?
컴퓨터는 전기로 작동하기 때문입니다.
따라서
전기가 흐르는 상태를 1
전기가 흐르지 않는 상태를 0
으로 하여 표현을 하게 됩니다.
이렇게 전기적 상태를 숫자로
사용하기 위해
컴퓨터는 이진수를 사용하게 됩니다.
0,1 을 저장할 수 있는 최소 메모리 공간을
비트라고 합니다.
1비트에 저장할 수 있는 수는
0과 1 두 가지입니다.
그러면 2비트에 저장할 수 있는
수는 몇 가지 일까요?
00,01,10,11
바로 네 가지입니다.
경우의 수를 따져
1비트 = 2
2비트 = 4
3비트 = 8
즉,
n비트 = 2^n (n제곱)
n비트로 저장할 수 있는 수는
2^n 개입니다.
8개의 연속된 비트를 바이트(byte)라고 합니다.
8개의 비트로 이루어져 있으니
저장할 수 있는 수는 몇개일까요?
바로 256개 입니다!
컴퓨터는 이 이진수를 통해 연산을 처리하지만
우리가 c언어를 통해 표현할 수 있는 수의 체계는
2진수, 8진수, 10진수, 16진수가 있습니다.
우리가 일상생활에서 흔히 사용하는
10진수는
각 자리마다 0~9까지의 숫자를 사용하고
10이 되면 다음 자리수로 넘어가게 됩니다.
9다음 10이 되는 것이죠.
나머지도 마찬가지 입니다.
2진수는 0,1 다음에 자리수가 넘어가고
8진수는 0,....,7 다음 자리수가 넘어가고
16진수는 0,.....,15 다음 자리수가 넘어갑니다.
우리는 대부분 10진수 체계를 기준으로
수를 세고 표현하기 때문에
2진수, 8진수, 16진수를
10진수로 변환할 수 있습니다.
8진수를 예로 들겠습니다.
2 7
2*(8^1) + 7*(8^0)
= 16 + 7 = 23
8진수 27은 10진수로 23이 됩니다.
16진수는
0~9까지는 수로 표기하지만
10~15까지는
a, b, c, d, e, f 문자를 사용해 표기합니다.
a=10
b=11
c=12
d=13
e=14
f=15
16진수를 예로 들어보겠습니다.
a 9
10*(16^1) + 9*(16^0)
=160 + 9 =169
16진수 a9는 10진수로 169가 됩니다.
이렇게 각 수의 체계를 10진수로
변환하는 방법을 알고 있으면
편합니다.
또
2진수를 8진수,16진수로
8진수,16진수를 2진수로
변환하는 방법은
아주 간단합니다.
2진수를 8진수로 변환한다고 예를 들면
2진수를 10진수로 변환시키고
8진수로 변환 시킬 필요없이
2진수와 8진수의 관계를 이해하면
쉽게 구할 수 있습니다.
2진수를 3묶음으로 보면
2^3 = 8로 표현할 수 있는
숫자의 수는 8개 입니다.
또한 4묶음으로 보면 2^4 = 16으로
표현할 수 있는 숫자의 수는 16개
입니다.
뭐가 보이시나요?
바로 각각 3개, 4개씩 묶어서 8진수, 16진수로 표현할 수 있다는 것입니다.
2진수 10110100을
3개, 4개씩 묶어서
264, b4로 표현한 것입니다.
2의 보수
위에서 비트체계를 알아봤습니다.
그런데 한 가지 의문점이 생길 것 입니다.
과연 음수는 어떻게 표현할 것인가?
바로 음수를 표현하기 위해 컴퓨터에서는
2의 보수라는 개념이 사용됩니다.
8비트의 공간이 있을 때
0 0 1 1 0 0 1 0
이라는 숫자를 가정해봅시다.
2의 보수는 각 비트를 반전 시키고
1을 더한 값입니다.
반전
1 1 0 0 1 1 0 1
+1
1 1 0 0 1 1 1 0
0 0 1 1 0 0 1 0
를 십진수로 표현하면 50이기 때문에
1 1 0 0 1 1 1 0
는 십진수로 표현하면 -50이 됩니다.
과연 이게 맞는 데이터인지 확인해볼까요?
0 0 1 1 0 0 1 0
과
1 1 0 0 1 1 1 0
를 더하게 되면
(1) 0 0 0 0 0 0 0 0
이 됩니다.
여기서 1은 8비트 공간에서
오버플로우 되기 때문에
유효한 데이터로 간주하지 않습니다.
따라서
0 0 0 0 0 0 0 0 0
으로 인식하게 되어
결과값은 0이 됩니다.
이렇게 컴퓨터에서는 음수를 2의 보수로 표현한다는
것을 알아봤습니다.
비트 연산자
연산자 | 설명 |
& | 비트 단위 AND 연산 |
| | 비트 단위 OR 연산 |
^ | 비트 단위 XOR 연산 |
~ | 비트 단위 NOT 연산 |
<< | 왼쪽 shift 연산 |
>> | 오른쪽 shift 연산 |
이진수
1011 와 0101
으로 & 연산을 해봅시다.
1 0 1 1
0 1 0 1
0 0 0 1
여기서 중요한 것은
비트 단위 연산이므로
한 비트씩 연산을 해주는 것입니다.
AND 연산은 두 비트가 1이어야만
1이 됩니다!
이번엔
1011 와 0101
으로 | 연산을 해봅시다.
1 0 1 1
0 1 0 1
1 1 1 1
OR 연산은 두 비트중 한 비트만
1이어도 1이 됩니다!
XOR 연산은 비교하고자 하는 비트가
서로 달라야지만 결과값이 1이 됩니다.
1 0 1 1
0 1 0 1
1 1 1 0
이해 되시죠?
NOT연산은
비트 단위로 반전을 해주시면 됩니다.
논리 연산자와 헷갈리면 안 됩니다!
shift 연산자를 쓰는 법을 배워보겠습니다.
왼쪽 shift 연산부터 보자면
0 1 0 0 1 0 0 1
에 <<1을 해주면
왼쪽으로 한 칸씩 이동을 하게 됩니다.
1 0 0 1 0 0 1 ?
한 칸씩 이동을 하게 되면
맨 왼쪽에 있는 비트는 사라지게 되고
맨 오른쪽 비트에는 빈공간이 생기게 됩니다.
왼쪽 shift 연산의 경우에는
무조건 0을 채우게 됩니다.
그러면 결과값은
1 0 0 1 0 0 1 0
이 됩니다.
여기서
0 1 0 0 1 0 0 1
는 십진수로 73이고
1 0 0 1 0 0 1 0
는 십진수로 146입니다.
뭐가 보이시나요?
바로 왼쪽 shift 연산을 한 값이
연산 전 값에 두 배라는 것을 볼 수 있습니다.
각 자리수의 가중치가 2의 배수만큼 늘었기 때문입니다.
왼쪽 shift연산을 n만큼 하면 2^n를 곱한만큼
만큼 값이 증가한다는 것을 알 수 있습니다.
오른쪽 shift 연산은
왼쪽 shift 연산과 반대로 오른쪽으로
이동을 하게 됩니다.
1 1 0 0 1 0 0 1
에 >>1을 해주면
오른쪽으로 한 칸씩 이동을 하게 됩니다.
? 1 1 0 0 1 0 0
위에서 2의 보수에 대해
알아봤는데
제일 첫 번째 비트는 부호를 의미합니다.
8비트의 공간에서 첫 번째 비트가
1이기 때문에 위의 수는 음수이고
부호에 맞춰서
빈공간에 수를 넣어주면 됩니다.
음수를 오른쪽 shift 연산 해주면
1을 채워주면 되고
양수를 오른쪽 shift 연산 해주면
0을 채워주면 됩니다.
따라서 결과값은
1 1 1 0 0 1 0 0
이 됩니다.
왼쪽 shift 연산자와 반대로
오른쪽 shift연산을 n만큼 하면 2^n를 나눈만큼
만큼 값이 감소한다는 것을 알 수 있습니다.
마무리
오늘은 비트 체계와 비트 연산자에 대해
알아봤습니다.
다음 글로는 c언어의 자료형에 대해
배워보겠습니다.
오늘도 글 봐주셔서 감사합니다.
'프로그래밍언어 > c언어' 카테고리의 다른 글
C언어 독학 #9. 반복문 (2) | 2022.07.09 |
---|---|
C언어 독학 #8. 자료형 (0) | 2020.07.18 |
C언어 독학 #6. 연산자 (0) | 2020.05.13 |
C언어 독학 #5. 상수 변하지 않는 데이터 (2) | 2020.05.12 |
C언어 독학 #4. 변수 데이터를 저장하자 (6) | 2020.04.22 |