Uing? Uing!!

[Kotlin] ushr(>>>)와 shr(>>) 의 차이 본문

Kotlin

[Kotlin] ushr(>>>)와 shr(>>) 의 차이

Uing!! 2022. 5. 2. 18:32
반응형

자바 내부에서 bitCount를 세는 방식을 찾아보니 아래와 같이 카운팅하고 있었다.

    /**
     * Returns the number of one-bits in the two's complement binary
     * representation of the specified {@code int} value.  This function is
     * sometimes referred to as the <i>population count</i>.
     *
     * @param i the value whose bits are to be counted
     * @return the number of one-bits in the two's complement binary
     *     representation of the specified {@code int} value.
     * @since 1.5
     */
    @HotSpotIntrinsicCandidate
    public static int bitCount(int i) {
        // HD, Figure 5-2
        i = i - ((i >>> 1) & 0x55555555);
        i = (i & 0x33333333) + ((i >>> 2) & 0x33333333);
        i = (i + (i >>> 4)) & 0x0f0f0f0f;
        i = i + (i >>> 8);
        i = i + (i >>> 16);
        return i & 0x3f;
    }

shift 연산은 >>나 <<인게 기억이 났는데, >>> 연산이 뜻하는 바가 헷갈렸다.

kotlin으로 가져와보니 이렇게 변환된다.

@HotSpotIntrinsicCandidate
fun bitCount(i: Int): Int {
    // HD, Figure 5-2
    var i = i
    i = i - (i ushr 1 and 0x55555555)
    i = (i and 0x33333333) + (i ushr 2 and 0x33333333)
    i = i + (i ushr 4) and 0x0f0f0f0f
    i = i + (i ushr 8)
    i = i + (i ushr 16)
    return i and 0x3f
}

오랜만에 ushr, shr의 차이를 찾아 보니 옛날에 배웠던 기억이 났다.

 

shr는 shift right로 바이너리를 n칸 오른쪽으로 밀면서 앞에 1을 채워넣어 기존의 positive/negative 비트를 유지한다.

반면 ushr는 unsigned shift right로, 똑같이 바이너리를 n칸 오른쪽으로 밀지만, unsigned이므로 첫 번째 비트를 부호로 인식하지 않아서, 앞에 1대신 0을 채워넣는다.

 

추후에 기억하기 위해 각각의 의미를 정리해 둔다.

예시에 사용된 숫자 -5는 binary로 11111111111111111111111111111011​이다.

Java Kotlin 의미 예시(Kotlin) 결과
>> shr shift right 0b1111 shr -5 11111111111111111111111111111101
>>> ushr unsigned shift right 0b1111 ushr -5 01111111111111111111111111111101

 

반응형
Comments