비트연산과 진수

2024. 2. 23. 17:48알고리즘

  • 비트와 바이트

1 bit : 0과 1을 표현하는 정보의 단위

1 byte : 8 bit가 1 바이트 이다.

ex) 16비트는 2바이트이다.

 

  • 비트 연산

컴퓨터 CPU는 0과 1로 동작되며, 내부적으로 비트 연산을 사용하여 덧셈, 뺄셈, 곱셈 등을 계산한다.

 

AND = & : a, b 둘 다 1 일때만 결과가 1이고 그 외에는 0

OR = | : a, b 둘 중 하나만 1이어도 결과가 1이고 그 외에는 0

 

ex)

7 = 0b111

5 = 0b101

print(7 & 5) = 5

print(7 | 5) = 7

 

10진수를 2, 16진수로 변환

print(bin(10))  # 0b1010
print(hex(10))  # 0xa

 

2, 16진수 문자열을 10진수로 변환 (int 뒤에 받는 변수가 문자열임에 주의!!!)

print(int('1011', 2))   # 2진수 / 11
print(int('b', 16))     # 16진수 / 11

 

  • XOR 연산자 = ^

같으면 0, 다르면 1

NOT 이 아니다!

 

어떤 값이던 임의의 수로 2회 XOR 하면 원래 수로 돌아온다.

7070 ^ 1004 = 6258

6258 ^ 1004 = 7070

위 사례에서 임의의 수는 1004 인데 이 값을 둘이서만 비밀코드로 공유하면

암호화에 사용될 수 있다. 6258 이라는 암호를 보내면 비밀코드로 이를 해석해서 원래 메세지를 밝힘

KEY = 1004

def encode_decode(num):
    return num ^ KEY

print(encode_decode(1000))  # 4
print(encode_decode(4))     # 1000

 

  • Left와 Right Shift 연산자

<< : 피연산자의 비트열을 특정 수 만큼 왼쪽으로 밀어낸다. (우측에 0이 생성됨)

>>: 피연산자의 비트 열을 특정 수 만큼 오른쪽으로 밀어낸다. (우측 비트들이 제거된다.)

t = 1
for i in range(5):
    print(bin(t), t)
    t <<= 1

# 0b1 1
# 0b10 2
# 0b100 4
# 0b1000 8
# 0b10000 16

 

  • 비트 연산 응용

1 << n = 2**n

 

i & (1 << n)

i의 n번 비트가 1인지 아닌지를 확인할 수 있다.

ex) 1101 & (1<<2) 연산으로 1101 에서 2번 bit가 1인지 확인 가능하다.

연산 결과가 0 이라면, n번 비트가 0임이 확정된다.

 

  • 음수 표현 방법

컴퓨터는 음수를 ‘2의 보수’로 관리한다.

MSB = 가장 높은 자리의 비트 = 맨 앞자리 bit

이 MSB가 음수, 양수를 구분하는 비트인데, 1이면 음수, 0이면 양수다!

 

  • 2의 보수 구하는 법

뒤집는다 → + 1 한다.

ex)

10001 의 2의 보수 → 01110 + 1 = 01111

11100 의 2의 보수 → 00011 + 1 = 00100

 

  • -5 를 2의 보수로 표현하는 방법 (수를 8 bit로 저장하는 경우)

5를 2진수로 나타내면 000 0101 이다. (7 bit)

-5는 음수이기에 MSB는 1이다.

나머지 7 bit에 대해 수를 뒤집고 1을 더하면 된다. (2의 보수)

5를 뒤집으면 111 1010 이며, 1을 더하면 111 1011 이 된다.

-5는 음수기에 MSB는 1이다. 따라서 1111 1011 이 된다.

 

  • NOT 연산자 = ~

모든 비트를 반전시킨다.

만약 8 bit 일때 ~(0001 1111) 이라면 값은 1110 0000

 

ex) 파이썬에서 print(~4) = -5 이다.

→ 4 는 0b0100 (MSB 는 양수이므로 0)

cf) 2진수는 보통 4개씩 끊어서 계산한다

NOT 연산자로 뒤집으면 1011 이 된다.

MSB는 1이 되었고 (음수) 나머지 bit 는 011 이다.

나머지 bit에 대해 2의 보수를 취하면 100 + 1 = 101 이므로 5가 된다.

따라서 -5 가 된다.

 

  • 실수

파이썬에서는 실수 출력 방법으로 f-string 문법을 지향한다.

t1 = 10
t2 = 3.141592

print(f'변수 값은 {t1} 입니다')
print(f'변수 값은 {t2:.2f} 입니다')

# 변수 값은 10 입니다
# 변수 값은 3.14 입니다

 

컴퓨터는 실수를 내부에서 근사적으로 관리한다.

실수는 정확한 값이 아니라 근삿값으로 저장되는데, 이때 생기는 작은 오차가 계산 과정에서 다른 결과를 가져온다.

print(0.1 + 0.1 + 0.1 == 0.3)
# False
n = 0.1
print(f'{n:.20f}')

# 0.10000000000000000555

→ 실수는 정확한 값이 아니라 근삿값이다.

 

  • 근삿값으로 저장되는 원리

소수점이 있는 10진수를 2진수로 변환하는 예시

0.75 = 2**-1 + 2**-2 = 이진수 0.11

 

소수점을 포함한 이진수 실수를 10진수로 변환하기

이진수 0.0011 = 12**-3 + 12**-4 = 0.1875

'알고리즘' 카테고리의 다른 글

부분 집합, 조합, 탐욕 알고리즘  (2) 2024.02.29
반복과 재귀, 순열, 완전 탐색  (1) 2024.02.27
알고리즘 응용 준비  (0) 2024.02.22
Tree (2)  (0) 2024.02.21
Tree  (0) 2024.02.20