1. 비트 연산자(Bitwise Operators)
& (Binary AND) : bit 단위로 and연산을 한다.
| (Binary OR) : bit 단위로 or연산을 한다.
^ (Binary XOR) : bit 단위로 xor연산을 한다.
~ (Binary NOT) : bit 단위로 not연산을 한다.(1의 보수)
<< (Binary left Shift) : bit 단위로 왼쪽으로 비트단위 밀기 연산을 한다.
>> (Binary right Shift) : bit 단위로 오른쪽으로 비트단위 밀기 연산을 한다.
- 비트 단위로 연산을 수행한다.
- 0은 거짓으로 1은 참으로 연산하여 결과를 1과 0으로 반환한다.
- "^(xor)"연산은 두개의 값이 다를 때만 참인 연산이다.
- " ~(not)" 연산은 1의 보수를 구한다. 컴퓨터에서는 뺄셈을 2의 보수를 덧셈하여 처리한다.
- "<<"는 연산은 왼쪽으로 1비트 밀때마다 두 배씩 늘어난다.
- ">>" 연산은 오른쪽으로 1비트 밀때마다 1/2씩 줄어든다.
- n << m : n * 2의 m승
- n >> m : n / 2의 m승
진법의 초기화 및 출력 그리고 변환
# 진법 초기화
a = 10
print(type(a), a)
a = 0b10
print(type(a), a)
a = 0o10
print(type(a), a)
a = 0x10
print(type(a), a)
print()
a = 0B10
print(type(a), a)
a = 0O10
print(type(a), a)
a = 0X10
print(type(a), a)
print("-"*20)
# 출력
i = 0x100
print("i = ", i)
print("i = ", bin(i))
print("i = ", int(i))
print("i = ", oct(i))
print("i = ", hex(i))
print("-"*20)
# 문자열을 형변환
i = "111"
print("i = ", int(i))
print("i = ", int(i, 2))
print("i = ", int(i, 8))
print("i = ", int(i, 16))
print("i = ", int(i, 5))
print("-"*20)
실행 결과
<class 'int'> 10
<class 'int'> 2
<class 'int'> 8
<class 'int'> 16
<class 'int'> 2
<class 'int'> 8
<class 'int'> 16
--------------------
i = 256
i = 0b100000000
i = 256
i = 0o400
i = 0x100
--------------------
i = 111
i = 7
i = 73
i = 273
i = 31
--------------------
기본 연산
# 비트 연산자(Bitwise Operators)
a = 0b10101010
b = 0b01110011
print('a = ', a, ":", bin(a))
print('b = ', b, ":", bin(b))
print('a & b = ', a & b, ":", bin(a & b))
print('a | b = ', a | b, ":", bin(a | b))
print('a ^ b = ', a ^ b, ":", bin(a ^ b))
print('~a = ', ~a, ":", bin(~a))
a = 0b1
print('a = ', a)
a = a << 1 # * 2
print('a = ', a)
a = a << 1 # * 2
print('a = ', a)
a = a << 3 # * 2**3
print('a = ', a)
a = a >> 1 # / 2
print('a = ', a)
a = a >> 1 # / 2
print('a = ', a)
a = a >> 2 # / 2**2
print('a = ', a)
실행 결과
a = 170 : 0b10101010
b = 115 : 0b1110011
a & b = 34 : 0b100010
a | b = 251 : 0b11111011
a ^ b = 217 : 0b11011001
~a = -171 : -0b10101011
a = 1
a = 2
a = 4
a = 32
a = 16
a = 8
a = 2
2. 비트 연산자(Bitwise Operators) 활용
2의 누승 출력하기
# 비트 연산자(Bitwise Operators)
# 2의 누승 출력하기
a = 1
for i in range(0, 11):
print('{0:6,}'.format(a << i), end=' ')
print()
a = 2
for i in range(0, 11):
print('{0:6,}'.format(a ** i), end=' ')
print()
a = 1024
for i in range(0, 11):
print('{0:6,}'.format(a >> i), end=' ')
print()
a = 2
for i in range(10, -1, -1):
print('{0:6,}'.format(a ** i), end=' ')
print()
실행 결과
1 2 4 8 16 32 64 128 256 512 1,024
1 2 4 8 16 32 64 128 256 512 1,024
1,024 512 256 128 64 32 16 8 4 2 1
1,024 512 256 128 64 32 16 8 4 2 1
보수를 이용한 밸셈
# 2의 보수를 이용한 뺄셈
# ~(1의보수) + 1 = 2의 보수
a = 10
b = 3
c = a - b
d = a + (~b + 1)
print('a - b = ', c)
print('a + (~b + 1) = ', d)
실행 결과
a - b = 7
a + (~b + 1) = 7
두개의 숫자를 교환하기
# 두개의 숫자를 교환하기
a = 100
b = 200
print('a={0}, b={1}'.format(a,b))
# 임시 변수를 사용하는 방법
temp = a
a = b
b = temp
print('a={0}, b={1}'.format(a,b))
# Python의 tuple을 이용하는 방법
a, b = b, a
print('a={0}, b={1}'.format(a,b))
# ^(xor)연산자를 이용하는 방법
a = a ^ b
b = a ^ b
a = a ^ b
print('a={0}, b={1}'.format(a,b))
실행 결과
a=100, b=200
a=200, b=100
a=100, b=200
a=200, b=100
10진수를 입력받아 16진수로 출력하기
# 10진수를 입력받아 16진수로 출력하기
while True:
n = int(input('정수입력(1~255사이, 0은종료)'))
if not n:
break
if n<0 or n>255: # 0x00 ~ 0xFF 사이의 숫자
print('올바른 범위의 정수를 입력하시오')
continue
high = n >> 4 & 0XF # 상위 4비트만 뽑아내기
low = n & 0XF # 하위 4비트만 뽑아내기
print('원본 : ', bin(n))
print('8비트중 상위 4비트 : ', bin(high))
print('8비트중 하위 4비트 : ', bin(low))
print('사용자 : 0X{0:1}'.format(high if high < 10 else chr(ord('A') + high-10)), end='')
print('{0:1}'.format(low if low < 10 else chr(ord('A') + low-10)))
print('파이선 : {}'.format(hex(n)))
실행 결과
정수입력(1~255사이, 0은종료)255
원본 : 0b11111111
8비트중 상위 4비트 : 0b1111
8비트중 하위 4비트 : 0b1111
사용자 : 0XFF
파이선 : 0xff
정수입력(1~255사이, 0은종료)128
원본 : 0b10000000
8비트중 상위 4비트 : 0b1000
8비트중 하위 4비트 : 0b0
사용자 : 0X80
파이선 : 0x80
정수입력(1~255사이, 0은종료)78
원본 : 0b1001110
8비트중 상위 4비트 : 0b100
8비트중 하위 4비트 : 0b1110
사용자 : 0X4E
파이선 : 0x4e
정수입력(1~255사이, 0은종료)0
10진수를 입력받아 2진수 출력하기
# 10진수를 입력받아 2진수로 출력하기
while True:
n = int(input('정수입력(1~255사이, 0은종료)'))
if not n:
break
if n<0 or n>255: # 0x00 ~ 0xFF 사이의 숫자
print('올바른 범위의 정수를 입력하시오')
continue
mask = 0b10000000 # 8비트 중 상위 1비트만 1인 수
print('사용자 : {}을 2진수로 출력하면 0b'.format(n), end='')
# 8번 반복
# 1이 오른쪽으로 1칸씩 이동하며 mask와 and 연산을 수행
# 지정 위치의 값이 1일때만 같은 수가되고 0이면 0이 된다.
# 같은때는 1을 다를때는 0을 출력하면 2진수
for i in range(0,8):
print('1' if (mask & n) == mask else '0', end='')
mask = mask >> 1
print()
print('파이썬 : {0}을 2진수로 출력하면 {1}'.format(n, bin(n)))
실행 결과
정수입력(1~255사이, 0은종료)1
사용자 : 1을 2진수로 출력하면 0b00000001
파이썬 : 1을 2진수로 출력하면 0b1
정수입력(1~255사이, 0은종료)2
사용자 : 2을 2진수로 출력하면 0b00000010
파이썬 : 2을 2진수로 출력하면 0b10
정수입력(1~255사이, 0은종료)3
사용자 : 3을 2진수로 출력하면 0b00000011
파이썬 : 3을 2진수로 출력하면 0b11
정수입력(1~255사이, 0은종료)4
사용자 : 4을 2진수로 출력하면 0b00000100
파이썬 : 4을 2진수로 출력하면 0b100
정수입력(1~255사이, 0은종료)5
사용자 : 5을 2진수로 출력하면 0b00000101
파이썬 : 5을 2진수로 출력하면 0b101
정수입력(1~255사이, 0은종료)6
사용자 : 6을 2진수로 출력하면 0b00000110
파이썬 : 6을 2진수로 출력하면 0b110
정수입력(1~255사이, 0은종료)7
사용자 : 7을 2진수로 출력하면 0b00000111
파이썬 : 7을 2진수로 출력하면 0b111
정수입력(1~255사이, 0은종료)8
사용자 : 8을 2진수로 출력하면 0b00001000
파이썬 : 8을 2진수로 출력하면 0b1000
정수입력(1~255사이, 0은종료)255
사용자 : 255을 2진수로 출력하면 0b11111111
파이썬 : 255을 2진수로 출력하면 0b11111111
정수입력(1~255사이, 0은종료)0
색상 값 분리하기/결합하기
색상 값은 어떻게 나타낼까?
- 대부분 4Byte로 Alpha, Red, Green, Blue를 이용하여 나타냅니다.
- 2진수 4자리는 16진수 1자리이다. 1Byte는 8Bit이므로 16진수 2자리로 표현 가능한다.
- and 연산은 값을 지울 때 사용한다.
- 0으로 &연산하면 0이고 1로 &연산하면 통과이다.
- or 연산은 값을 설정할 때 사용한다.
- 0으로 |연산하면 통과이고 1로 |연산하면 1이다.
.
# 색상분리
color = 0xAABBCCDD
alpha = color >> 24 & 0xFF
red = color >> 16 & 0xFF
green = color >> 8 & 0xFF
blue = color & 0xFF
print(color, hex(color))
print(alpha, hex(alpha))
print(red, hex(red))
print(green, hex(green))
print(blue, hex(blue))
# 색상 결합
color2 = 0
print(color2, hex(color2))
color2 = color2 | alpha << 24
print(color2, hex(color2))
color2 = color2 | red << 16
print(color2, hex(color2))
color2 = color2 | green << 8
print(color2, hex(color2))
color2 = color2 | blue
print(color2, hex(color2))
# red값 만 삭제
color2 = color2 & 0xFF00FFFF
print(color2, hex(color2))
# red값을 56으로 설정
color2 = color2 | 0x00560000
print(color2, hex(color2))
실행 결과
2864434397 0xaabbccdd
170 0xaa
187 0xbb
204 0xcc
221 0xdd
0 0x0
2852126720 0xaa000000
2864381952 0xaabb0000
2864434176 0xaabbcc00
2864434397 0xaabbccdd
2852179165 0xaa00ccdd
2857815261 0xaa56ccdd
테트리스 벽돌 출력하기
# 테트리스 벽돌을 출력해보자
brick = (0x0660, 0x0F00, 0x2222, 0x6220, 0x4460, 0x4640, 0x7200, 0x6300,0x4620)
for i in brick:
mask = 0b1000000000000000
for j in range(0,16):
print('■' if (mask & i) == mask else '□', end='')
if (j+1)%4==0:
print()
mask >>= 1
print()
실행 결과
□□□□
□■■□
□■■□
□□□□
□□□□
■■■■
□□□□
□□□□
□□■□
□□■□
□□■□
□□■□
□■■□
□□■□
□□■□
□□□□
□■□□
□■□□
□■■□
□□□□
□■□□
□■■□
□■□□
□□□□
□■■■
□□■□
□□□□
□□□□
□■■□
□□■■
□□□□
□□□□
□■□□
□■■□
□□■□
□□□□
아직까지 이진수와 16진수 그리고 반복문과 제어문을 모르기 때문에 어려울 것이다. 하지만 많은 응용프로그램에서 자주 사용되는 연산자이다. 숙지하시면 일반 프로그램 보다도 적은 소스로 우수한 성능을 발휘할 수 있는 연산자들이다.
'Python > Basic programming' 카테고리의 다른 글
파이썬의 Asterisk(`*`) 연산자 (0) | 2020.03.15 |
---|---|
보수 개념과 파이썬 `~x` 연산 (Bitwise reversion) (0) | 2020.03.15 |
파이썬 연산자와 그에 대응하는 함수 (0) | 2020.03.15 |
문자열과 관련된 함수들 (0) | 2020.03.12 |
리스트 한 줄에 출력하기 (0) | 2020.03.12 |