이 조각은 먼저 가장 높은 세트 비트 아래의 모든 비트를 채 웁니다. v |= v >> 1
이후 처음 두 비트를 복사 할 수 있습니다. 마지막으로 값이 1 씩 증가합니다. 그렇지 않으면 결과는 항상 0
것이기 때문에 부호 비트가 시프트 조작으로 확장됩니다 때문에
uint32_t v = ...;
v |= v >> 1;
v |= v >> 2;
v |= v >> 4;
v |= v >> 8;
v |= v >> 16;
v += 1;
uint32_t
의 unsigned
부분은 중요하다. 값이 uint64_t
인 경우 추가 시프트를 추가해야하며 uint16_t
인 경우 교대를 제거해야합니다.
입력이 8 일 경우 결과는 16이됩니다. 원하지 않으면 입력이 2의 거듭 제곱인지 테스트해야합니다. . 당신이 (8 = 0b1000, 7 = 0b111)를 감소,이 가드 사용할 수있는 경우 2의 거듭 제곱의 이진 표현이 하나 개의 문자 짧은 것을 알고 : https://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2에서
if ((v & (v - 1)) > 0) {
…
}
(메모리에서 재현 원본을, 더 많은 흥미로운 트릭이 포함되어 있습니다.)
출처
2014-09-17 01:12:35
kay
왜 실행하고 테스트하여 작동하는지보십시오. – indiv
'2^p'를 다루는 핵심 요소 인'(1 << p)'가 공식에서 누락되어서 그것이 옳지 않다고 확신합니다. [이 페이지] (https://graphics.stanford.edu/~seander/bithacks.html)를 보시면 필요한 것이있을 수 있습니다. – dasblinkenlight
코드를 직선 코드로 테스트하고 테스트 한 다음 매크로로 변환합니다. – lboshuizen