Bit & 연산자
https://jeongchul.tistory.com/730
위의 Snow Flake에서 시퀀스의 최대 값을 4096(12비트)로 값을 0~4095로 고정하는 코드가 있습니다.
uint64_t next_id(Snowflake *sf) {
uint64_t timestamp = current_time_millis();
if (timestamp == sf->lastTimestamp) {
sf->sequence = (sf->sequence + 1) & MAX_SEQ; // <--------- 범위 고정
if (sf->sequence == 0) {
while (timestamp <= sf->lastTimestamp) { // 다음 밀리초가 될 때까지 대기
timestamp = current_time_millis();
}
}
} else { // 새로운 밀리초에 진입했을 때
sf->sequence = 0; // 시퀀스 초기화
}
...
}
&
연산자는 비트 단위의 AND 연산을 수행합니다. 이 연산은 시퀀스 값이 일정 범위를 넘지 않도록 하기 위한 중요한 역할을 합니다.
& 연산자의 의미
&
는 비트 AND 연산자로, 두 개의 값의 비트를 비교하여 둘 다 1인 경우에만 1을 반환합니다. 예를 들어:
1 & 1 = 1
1 & 0 = 0
0 & 0 = 0
즉, AND 연산자는 각 비트에 대해 AND 연산을 적용하여 새로운 값을 만듭니다.
MAX_SEQ의 역할
#defin SEQ_BITS 2
#define MAX_SEQ ((1 << SEQ_BITS) - 1)
- 위 코드에서
MAX_SEQ
는 시퀀스가 가질 수 있는 최대값을 정의합니다. SEQ_BITS
가 2비트로 설정되어 있으므로,1 << SEQ_BITS
는2^2 = 4
이 됩니다.MAX_SEQ
는 이 값에서 1을 뺀 값으로, 3가 됩니다. 즉, 시퀀스 번호는 0부터 3까지 가질 수 있습니다.
AND 연산자 사용 목적
sf->sequence = (sf->sequence + 1) & MAX_SEQ;
이 부분에서 & MAX_SEQ
의 목적은 시퀀스 값이 2비트 범위를 초과하지 않도록 하는 것입니다.
동작 원리
sf->sequence + 1
은 시퀀스 값을 1 증가시킵니다. 이때 시퀀스가MAX_SEQ
(3)보다 크면, 2비트 범위를 넘을 수 있습니다.& MAX_SEQ
는 2비트 이상 넘어간 값을 자르는 역할을 합니다. 즉,sf->sequence
값이 4가 되면 2비트 이상의 비트는 잘리고, 다시 0으로 돌아갑니다. 이를 통해 시퀀스 값은 항상 0부터 3까지의 값을 가집니다.
예시
만약 시퀀스가 1일 때, 다음과 같은 일이 일어납니다.
- 1+ 1 = 2 (이진수:
010
) 시퀀스 증가 - 011 & 010: & 연산 비교
3
의 이진수는011
2
의 이진수는010
- 이 둘을 AND 연산하면
010
이 되어 결과는 2가 됩니다.
이렇게 증가하여 시퀀스가 3일때, 다음과 같은 일이 일어납니다.
- 3 + 1 = 4 (이진수:
100
) 시퀀스 증가 → 2 비트, 범위를 초과하게됨 - 011 & 100: & 연산 비교
3
의 이진수는011
4
의 이진수는100
- 이 둘을 AND 연산하면
000
이 되어 결과는 0이 됩니다. - 이를 통해 3에서 시퀀스 증가 시, 2비트를 넘어가지 않고 다시 0으로 초기화되어 0~3까지 범위를 유지합니다.
요약
sf->sequence = (sf->sequence + 1) & MAX_SEQ;
에서 & MAX_SEQ
는:
- 시퀀스 번호가 최대값인 4를 넘지 않도록 순환하는 역할을 합니다.
- 시퀀스가 최대값에 도달하면 0으로 초기화되어 같은 밀리초 내에서 새로운 시퀀스를 부여하게 됩니다.
'Interview > C' 카테고리의 다른 글
C언어 Pointer (0) | 2024.10.17 |
---|---|
C언어 Shift 연산자 (0) | 2024.10.17 |