Python은 저수준 프로그래밍에 적합한 언어로 여겨지지 않지만 여전히 이를 위한 도구를 제공합니다. 그러한 도구 중 하나가 비트 연산자입니다.
Python의 비트 연산자는 암호화 알고리즘, 장치 드라이버 또는 예를 들어 네트워크 인프라 작업에 필요할 수 있는 이진 문자열을 수정하는 데 사용됩니다. 또한, 저수준 그래픽을 변경하거나 이진 코드로 다양한 동작을 수행해야 하는 기타 작업에도 유용할 수 있습니다.
파이썬에서 비트 연산자의 효과는 이진 코드에 대한 여러 유형의 논리 연산을 통해 비트 수준에서 객체를 수정하는 것입니다. 이 글에서는 이러한 작업에 대해 알아보겠습니다.
자연수의 비트 단위 출력
우리는 이진 코드, 특히 정수를 다루게 될 것이므로, 먼저 이러한 숫자를 필요한 형식으로 출력하는 방법을 알아보겠습니다. 이 작업은 매우 간단하게 수행됩니다.
>>> bin(5)
'0b101'
따라서 숫자 5의 이진수 표현이 있습니다. 하지만 이것이 정말 이진수일까요? 사실, 여기서 5는 마지막 세 자리 숫자( 101 )이고, 0b 코드는 Python에서 이진수 형태로 숫자를 출력하는 데 사용됩니다( 음수 값을 나타내는 – 0b 도 있습니다 ). 이제 우리는 이진 코드로 모든 숫자를 출력할 수 있으며, 0과 처음 10은 다음과 같습니다.
>>> bin(0)
0b0
>>> bin(1)
0b1
>>> bin(2)
0b10
>>> bin(3)
0b11
>>> bin(4)
0b100
>>> bin(5)
0b101
>>> bin(6)
0b110
>>> bin(7)
0b111
>>> bin(8)
0b1000
>>> bin(9)
0b1001
>>> bin(10)
0b1010
이 시리즈를 통해 숫자의 비트 표현 원리가 명확해졌습니다. 0이 차례로 1로 바뀌고, 모든 값이 1에 도달하면 새로운 숫자가 추가됩니다. 15까지 세어 봅시다.
>>> bin(11)
0b1011
>>> bin(12)
0b1100
>>> bin(13)
0b1101
>>> bin(14)
0b1110
>>> bin(15)
0b1111
네 번째 숫자는 소진(단위로 채워짐)되었으므로 다섯 번째 숫자가 적용되고 숫자 16과 17은 다음과 같이 작성됩니다.
>>> bin(16)
0b10000
>>> bin(17)
0b10001
따라서 이진 코드는 수학 법칙에 따라 엄격하게 구성됩니다. 3비트 숫자는 4에서 7까지의 숫자에 사용되고, 4번째는 8에서 15까지의 숫자에 추가되고, 5자리 숫자는 16에서 31까지의 숫자에 사용되고, 6자리 숫자는 32에서 63까지의 숫자에 사용되고, 7자리 숫자는 64에서 127까지의 숫자에 사용됩니다. 즉, 2를 곱한 다음 새로운 숫자가 추가됩니다. 이것은 서로 다른 비트 폭을 가진 피연산자를 비교할 때 유용합니다. 이 경우, 비트 수가 더 적은 피연산자의 0b 바로 뒤에 해당 개수만큼의 0이 추가될 수 있습니다 .
파이썬 기본 비트 연산자 유형
이제 다음 도구의 논리를 사용하여 비트를 조작할 준비가 되었습니다.
- & (그리고)
- | (또는)
- ^ (무료)
- ~ (아님)
- 교대근무
& (그리고, 그리고)
연산 논리: 두 비트(동일한 숫자)를 비교할 때, &
두 피연산자 모두에 비트가 있으면 1을 반환합니다(즉, 비트가 복사됨). 이 조건이 충족되지 않으면(즉, 피연산자 중 적어도 하나에서 비트가 누락됨) 0을 반환합니다. 이 작업은 &
다음과 같이 개략적으로 표현할 수 있습니다.
1&1=1
1&0=0
0&1=0
0&0=0
이는 가장 심각한 조건으로, 두 피연산자 모두에 있는 경우에만 비트가 반환됩니다(1이 주어짐). 이제 몇 가지 예를 들어보겠습니다.
>>> 3 & 6
2
왜냐하면:
3 = 0b011
6 = 0b110
2 = 0b010
표현의 편의를 위해 세 번째 자릿수를 추가하고 두 값 모두에 중간 비트만 있음을 확인합니다(각 숫자에 1). 따라서 반환된 숫자는 0b010, 즉 2입니다.
>>> 24 & 62
24
왜냐하면:
24 = 0b011000
62 = 0b111110
24 = 0b011000
흥미로운 결과는 일치하는 비트가 첫 번째 숫자를 표현하는 위치와 정확히 같은 위치에 있었기 때문에 나타났습니다.
>>> 555 & 878
554
555 = 0b1000101011
878 = 0b1101101110
554 = 0b1000101010
이제 더 복잡한 예를 살펴보겠습니다. 숫자의 자릿수가 다른 숫자를 연습해 보겠습니다.
>>> 80 & 755
80
80 = 0b0001010000
755 = 0b1011110011
80 = 0b0001010000
>>> 446 & 19
18
446 = 0b110111110
19 = 0b000010011
18 = 0b000010010
>>> 101 & 883
97
101 = 0b0001100101
883 = 0b1101110011
97 = 0b0001100001
클라우드 서버
전 세계적으로 확장 가능한 컴퓨팅 리소스, 시간당 청구계정 생성
| (또는)
연산 논리: 두 비트를 비교할 때, |
비교되는 피연산자 중 적어도 하나에 해당 비트가 있으면 1을 반환하고, 두 피연산자 모두에 해당 비트가 없으면 0을 반환합니다(비트가 복사됨). 이 작업은 |
다음과 같이 개략적으로 표현할 수 있습니다.
1|1=1
1|0=1
0|1=1
0|0=0
따라서 두 피연산자가 모두 0인 경우를 제외한 모든 경우에 비트가 반환됩니다. 예시:
>>> 9 | 5
13
9 = 0b1001
5 = 0b0101
13 = 0b1101
두 피연산자 모두 0을 가지고 있으므로 두 번째 자릿수(오른쪽부터)에서만 비트가 복사되지 않아 13이 반환됩니다.
>>> 87 | 59
127
87 = 0b1010111
59 = 0b0111011
127 = 0b1111111
>>> 846 | 657
991
846 = 0b1101001110
657 = 0b1010010001
991 = 0b1111011111
그리고 이미 익숙한 숫자이지만 완전히 다른 결과를 갖는 더욱 복잡한 작업:
>>> 80 | 755
755
80 = 0b0001010000
755 = 0b1011110011
755 = 0b1011110011
>>> 446 | 19
447
446 = 0b110111110
19 = 0b000010011
447 = 0b110111111
>>> 101 | 883
887
101 = 0b0001100101
883 = 0b1101110011
887 = 0b1101110111
^ (XOR, 배타적 OR)
연산 논리: 두 비트를 비교할 때 ^
, 비교되는 피연산자가 다르면 1을 반환하고(비트가 복사됨), 같으면 0을 반환합니다. 이 작업은 ^
다음과 같이 개략적으로 표현할 수 있습니다.
1^1=0
1^0=1
0^1=1
0^0=0
보시다시피, 연산자는 XOR
두 개의 1을 비교하든 두 개의 0을 비교하든 상관하지 않습니다. 두 경우 모두 비트는 반환되지 않습니다. 비트는 서로 다른 값을 비교할 때만 반환됩니다. 예시:
>>> 5 ^ 2
7
5 = 0b0101
2 = 0b0010
7 = 0b0111
가장 왼쪽의 숫자를 제외한 모든 숫자에서 피연산자가 일치하지 않았으므로 이 경우에는 비트가 반환되었습니다. 즉, 인터프리터는 1을 반환했습니다.
>>> 90 ^ 92
6
90 = 0b1011010
92 = 0b1011100
6 = 0b0000110
>>> 352 ^ 686
974
352 = 0b0101100000
686 = 0b1010101110
974 = 0b1111001110
숫자의 개수가 다른 피연산자를 사용한 몇 가지 예:
>>> 80 | 755
675
80 = 0b0001010000
755 = 0b1011110011
675 = 0b1010100011
>>> 446 | 19
429
446 = 0b110111110
19 = 0b000010011
429 = 0b110101101
>>> 101 | 883
790
101 = 0b0001100101
883 = 0b1101110011
790 = 0b1100010110
~ (아냐, 아니야)
~
값을 비교하지 않지만, 정수 값의 비트를 뒤집습니다. 양수는 1을 이동하면 음수로 변환되고, 그 반대의 경우도 마찬가지입니다. 작동 방식은 다음과 같습니다.
>>> ~0
-1
>>> ~30
-31
>>> ~-30
29
>>> ~80
-81
>>> ~-80
79
>>> ~255
-256
>>> ~-255
254
비트 단위 좌우 이동
왼쪽 이동은 기호로 표시하며 <<
, 변경할 숫자는 연산자의 왼쪽에 적고 이동에 필요한 비트 수는 연산자의 오른쪽에 표시됩니다.
>>> 1 << 1
2
우리는 1비트씩 이동하여 2를 얻었습니다. 그 이유는 다음과 같습니다.
1 = 0b01
2 = 0b10
즉, 해당 유닛이 한 위치 왼쪽으로 이동했습니다. 2만큼 옮기면 어떨까?
>>> 1 << 2
4
네, 4가 되는 이유는 다음과 같습니다.
1 = 0b001
4 = 0b100
1×3 위치로 이동하면 어떤 결과가 나올지 추측하기 어렵지 않습니다.
>>> 1 << 3
8
1 = 0b0001
8 = 0b1000
비트 레이아웃에 대한 몇 가지 예는 다음과 같습니다.
>>> 10 << 1
20
10 = 0b01010
20 = 0b10100
>>> 10 << 2
40
10 = 0b001010
40 = 0b101000
오른쪽 이동은 기호로 표시하며 >>
, 같은 방식으로 변경할 숫자는 왼쪽에 적고, 이동이 수행되는 비트 수는 연산자 오른쪽에 표시됩니다. 이는 역작업입니다. 즉,
>>> 2 >> 1
1
>>> 4 >> 2
1
>>> 8 >> 3
1
>>> 40 >> 1
20
>>> 40 >> 2
10