이 글에서는 비트 연산자(bit operator)를 활용하여 주어진 숫자가 양수인지, 음수인지, 아니면 0인지 확인하는 방법을 알아보겠습니다.
핵심 원리
32비트 정수에서 오른쪽 시프트 연산을 활용하면 부호 정보를 쉽게 추출할 수 있습니다.
n >> 31 연산은 산술 시프트(arithmetic shift) 방식으로 동작하기 때문에 다음과 같은 결과가 나타납니다.
- 음수일 경우: -1
- 양수 또는 0일 경우: 0
반대로 -n >> 31 연산을 수행하면 부호가 반전된 값에 시프트가 적용되므로, 양수일 때는 -1이 반환됩니다. 그런데 n이 0인 경우에는 n >> 31과 -n >> 31 모두 0을 반환하기 때문에 단순히 두 연산만으로는 세 가지 경우(양수·음수·0)를 구분할 수 없습니다.
판별 공식
이 문제를 해결하기 위해 아래와 같은 공식을 사용합니다.
1 + (n >> 31) - (-n >> 31)
이 공식의 결과값은 숫자의 종류에 따라 다음처럼 결정됩니다.
- n이 음수인 경우: 1 + (-1) - 0 = 0
- n이 양수인 경우: 1 + 0 - (-1) = 2
- n이 0인 경우: 1 + 0 - 0 = 1
즉, 결과값이 0이면 음수, 1이면 0, 2이면 양수임을 의미합니다.
C++ 구현 예제
#include <iostream>
#include <cmath>
using namespace std;
int checkNumber(int n){
return 1 + (n >> 31) - (-n >> 31);
}
int printNumberType(int n){
int res = checkNumber(n);
if(res == 0)
cout << n << " is negative" << endl;
else if(res == 1)
cout << n << " is Zero" << endl;
else if(res == 2)
cout << n << " is Positive" << endl;
}
int main() {
printNumberType(50);
printNumberType(-10);
printNumberType(70);
printNumberType(0);
}실행 결과
50 is Positive -10 is negative 70 is Positive 0 is Zero
정리
이 기법은 if-else 조건문이나 삼항 연산자 없이도 산술 시프트 연산만으로 숫자의 부호를 판별할 수 있다는 점이 특징입니다. 다만 이 방법은 32비트 정수(int) 환경에서만 동작하며, 컴파일러에 따라 오른쪽 시프트가 논리 시프트(logical shift)로 처리될 경우 결과가 달라질 수 있으므로 실무 적용 시에는 주의가 필요합니다.