`Bitwise`
Bitwise
비트 단위 계산을 수행하는 함수들을 모아 둔 모듈이에요.
모든 비트 연산 함수는 오직 정수(integer)에만 동작하며, 그 외의 값이 주어지면 ArithmeticError가 발생합니다. band/2, bor/2, bsl/2, bsr/2 함수는 각각 연산자 &&&/2, |||/2, <<</2, >>>/2로도 쓸 수 있어요.
Guards
모든 비트 연산 함수는 가드(guard)에서도 사용할 수 있습니다:
iex> odd? = fn
...> int when Bitwise.band(int, 1) == 1 -> true
...> _ -> false
...> end
iex> odd?.(1)
true
이 모듈의 모든 함수는 컴파일러가 인라인(inline) 처리합니다.
출처:
Bitwise
본문
비트 연산은 메모리에 저장된 값의 각 비트(0과 1)를 직접 조작하는 계산이에요. 일상적인 연산과 달리 숫자의 "칸 자체"를 다룬다고 생각하면 이해가 쉬워요. Bitwise 모듈은 이런 비트 수준의 계산에 쓰는 함수를 모아 두었고, 비트 연산이 자주 쓰이는 곳은 플래그를 조합해 상태를 표현할 때, 권한이나 설정을 비트로 묶어 관리할 때, 그리고 저수준 프로토콜을 다룰 때 등입니다.
핵심 연산은 네 가지예요. AND는 band/2(연산자 &&&/2), OR는 bor/2(|||/2), XOR은 bxor/2, 그리고 NOT은 bnot/1이 담당합니다. 여기에 비트를 좌우로 밀어내는 시프트 연산이 더해져요. bsl/2(<<</2)는 왼쪽으로, bsr/2(>>>/2)는 오른쪽으로 비트를 이동시킵니다. 정수에만 동작한다는 점을 꼭 기억하세요. 다른 값을 넣으면 ArithmeticError가 나옵니다.
각 함수는 곧장 계산 결과를 돌려줘요. 몇 가지 예를 볼게요.
iex> band(9, 3)
1
iex> bor(9, 3)
11
iex> bxor(9, 3)
10
iex> bnot(2)
-3
bnot/1이 -3을 돌려주는 건 조금 특별해요. Elixir의 정수는 음수를 2의 보수로 표현해서, 비트 NOT이 부호까지 뒤집어 버리기 때문입니다.
시프트 연산도 비슷하게 확인할 수 있어요.
iex> bsl(1, 2)
4
iex> bsl(1, -2)
0
iex> bsr(1, 2)
0
iex> bsr(1, -2)
4
왼쪽으로 밀면 값이 커지고 오른쪽으로 밀면 작아져요. 시프트 횟수가 음수면 방향이 반대로 바뀌죠. 위에서 bsl(1, -2)가 0인 이유는 "1을 왼쪽으로 -2칸", 즉 오른쪽으로 2칸 밀어서 비트가 사라졌기 때문이고, bsr(1, -2)는 반대로 왼쪽으로 2칸 밀어서 4가 된 거예요.
이 모든 함수는 가드에서도 쓸 수 있다는 점이 강점이에요. 위의 odd? 예시에서 Bitwise.band(int, 1) == 1로 홀짝을 판별했죠. 그리고 컴파일러가 인라인 처리하므로 성능 걱정 없이 함수 호출처럼 사용해도 됩니다.
더 알아보기
- 각 함수의 정확한 타입 시그니처는
@spec을 참고하세요. - 비트 연산이 유용하게 쓰이는 실제 사례는 표준 라이브러리에서 플래그나 상태 비트를 다루는 코드를 살펴보면 좋아요.
- 가드에서의 사용 제약은 Elixir 공식 가이드의 가드(guards) 문서에서 확인할 수 있습니다.