• 2의 보수를 사용하는 기계에서, 정수 i의 맨 아래쪽 1 비트(1로 세트된 비트 중 LSB에 제일 가까운 비트)를 0으로 만들려면 C 수식으로 i & (i-1)를 쓴다. 부호없는 정수로 생각하면, 1을 빼는 연산이 항상 맨 아래 비트를 0으로 만들고, 그보다 더 LSB쪽에 있는 비트는 1로 만든다는 것을 쉽게 알 수 있다.

    이 방법을 사용한 예는 Ken Thompson이 Unix에 썼다고 하는 전설이 있는 비트 수 세기 루프이다.

    /* i에 비트 수를 세고자 하는 값이 들어있다. */
    bitcount = 0;
    while (i != 0) {
        bitcount++;
        i &= i - 1;
    }
    이 코드는 2의 보수를 사용하는 모든 기계에서 작동한다.
  • 반대로, 2의 보수를 사용하는 기계에서 정수 i의 맨 아래쪽 1 비트만 남기고 다 지우려면, C 수식으로 i & -i를 쓴다. 이것도 2의 보수방식으로 부호를 바꾸는 연산이 NOT연산후에 1을 증가시킨다는 것을 기억하면 이 코드를 이해할 수 있다.

    이 방법을 응용하면, 어떤 정수가 2의 누승인지 쉽게 알아낼 수 있다. 이진법에서 2의 누승은 단 하나의 비트만 1이고 나머지 비트는 모두 0이다. 그러므로, 이렇게 하면 빨리 알아낼 수 있다:

    if ((i & -i) == i) { /* 2의 누승 */ }
    이 역시 머신워드 크기에 관계없이 2의 보수를 사용하는 모든 기계에서 작동한다.
  • 맨 아래쪽 1 비트가 몇번째 비트인지 알아내는 것은 루프를 돌아도 알아낼 수 있지만, 인텔계열 386이상의 CPU에서는 bsf명령을 쓰면 한번에 알 수 있다. BSD계통의 Unix에는 같은 목적으로 ffs()라는 함수가 제공된다.

Posted by movsd
,