비트연산
메모리 비트단위로 직접적인 논리연산을 수행하고, 비트 단위 이동시에 사용하는 연산
비트연산은 연산속도가 빠르다. 직접적으로 메모리의 실제 비트를 컨트롤하기 때문이다.
짧은 코드로 복잡한 로직을 구현할 수 있다.
비트 논리 연산자
[ ~ ] Bitwise Not Operator
~a
부정 연산자, 기존의 메모리 비트를 반전시킨다.
let a: UInt8 = 0b0000_1111 // 15
let b1 = ~a // 0b1111_0000 // 240
[ & ] Bitwise And Operator
a & b
비트 논리 곱 연산자.
let a: UInt8 = 0b0111_1000 // 120
let b: UInt8 = 0b1011_0111 // 183
let c = a & b//0b0011_0000 // 48
[ | ] Bitwise Or Operator
a | b
비트 논리 합 연산자
let a: UInt8 = 0b0111_1000 // 120
let b: UInt8 = 0b1011_0111 // 183
let c = a | b//0b1111_1111 // 255
[ ^ ] Bitwise Or Operator
a ^ b
비트 논리 베타 연산자. 서로 다르면 1을 반환한다.
let a: UInt8 = 0b0111_1000 // 120
let b: UInt8 = 0b1011_0111 // 183
let c = a ^ b//0b1100_1111 // 207
비트 이동 연산자 [ << , >> ]
부호가 없는 경우
- 기존 비트를 요청된 값만큼 왼쪽이나 오른쪽으로 이동한다.
- 정수의 수용 범위를 넘어서는 비트는 모두 버린다.
- 남는 공간에는 0을 삽입한다.
let a: UInt8 = 0b0000_1000 // 8
a << 1 // 0b0001_0000 // 16 ( a * 2^1)
a << 2 // 0b0010_0000 // 32 ( a * 2^2)
a << 5 // 0b0000_0000 // 0 ( a * 2^5) 이지만 허용 범위가 넘어갔으므로..
부호가 있는 경우
[ << ] 연산은 부호가 없는 경우와 동일하다.
[ >>] 연산인 경우, 특히 -인 경우에는 MSB(최상위비트)가 1임을 유지해야 하기 때문에, 0을 끼워넣지 않고 MSB를 1로 유지한 채 비트이동을 수행한다.
let a: Int8 = -2 // 0b1111_1110 // -2
a >> 1 // 0b1111_1111 // -1 ( a / 2^1) 의 몫
a >> 2 // 0b1111_1111 // -1 ( a * 2^2) 의 몫
a >> 5 // 0b1111_1111 // -1 ( a * 2^5) 의 몫