2010-05-23 3 views
2

내가 작업 할 5 비트 정수가 있습니다. Objective-C에서 어떤 비트가 가장 왼쪽인지 알 수있는 기본 함수가 있습니까?가장 왼쪽 비트 가져 오기

즉, 나는 01001을 가지고 있으며, 8 또는 위치를 반환합니다.

감사

+0

당신이 1 가장 왼쪽 비트를 의미합니까에서 _BitScanReverse/(64)를 보라 ++? 그것은 당신의 예제에서 보입니다. 그러나 ... –

답변

4
NSInteger value = 9; 
NSInteger shift = 1; 
for(NSInteger bit = value; bit > 1; bit = value >> ++shift); 
NSInteger leftmostbit = 1 << shift; 

모든 비트 수에 대해 작동합니다.

+3

이것을 위해'pow'를 사용하지 마십시오. 'pow'가 2의 정확한 힘을 전달한다는 언어 보장은 없습니다 (OS X에서 발생합니다. 질문은 'objective-c'라는 태그가 붙어 있기 때문에 대상이 될 수도 있지만, 이식성이있는 가정은 아닙니다). 또한 많은 플랫폼에서 비효율적입니다. 'leftmostbit = 1 << shift'를 원한다. –

+0

감사합니다. 당신 말이 맞습니다. 귀하의 의견에 따라 코드를 업데이트했습니다. – Joost

7

넌 32 개 요소, 룩업 테이블을 만들 수 0, 1, 2, 2, 3 등

+0

32 요소 룩업 테이블은이 특별한 경우를위한 가장 좋은 해결책입니다. –

+0

8 비트 정수의 경우에도 256 요소 테이블조차도 좋습니다. – ChrisW

+1

@Stephen : 비트 수를 ** 항상 ** 5 (또는 상대적으로 적은 수)로 100 % 확신하고 최적화를 절대로하고 싶지 않은 경우에만 가능합니다. SIMD 또는 GPGPU. –

6

이 효과적으로 선도 0의 그 수를 카운트하는 것과 동일한 동작이다. 일부 CPU에는 이에 대한 지침이 있습니다. 그렇지 않으면 Hacker's Delight에있는 것과 같은 트릭을 사용할 수 있습니다.

가장 가까운 2의 제곱으로 반올림하는 것과 동일하며, 다시 Hacker's Delight에서 효율적인 방법을 찾을 수 있습니다.

uint8_t flp2(uint8_t x) 
{ 
    x = x | (x >> 1); 
    x = x | (x >> 2); 
    x = x | (x >> 4); 
    return x - (x >> 1); 
} 

은 참조 : Previous power of 2

+1

두 개의 upvotes가 필요합니다. – Joshua

+1

'x | = x >> 1'도 마찬가지입니다. 훌륭한 솔루션! – Joost

0

당신은 어떤 비트의 값이 다음 오른쪽 (이하 "왼쪽"다섯 비트 값의)에서 위치 다섯 의미 경우

int value = 17; 
    int bit = (value >> 4) & 1; // bit is 1 

당신은 가장 왼쪽 비트의 위치를 ​​의미하는 경우 즉, 1 :

int value = 2; 
    int position; 
    for (position = 0; position < 5; position++) { 
      int bit = (value >> position) & 1; 
      if (bit == 1) 
        break; 
    } 
    // position is 1 

위치는 어디에 모든 비트 제로 경우 다섯 비트 값의 가장 왼쪽 비트 오른쪽 4 비트 먼 0 또는 5 일 것이다.

참고 : 이것은 클럭 사이클에서 가장 효과적인 솔루션이 아닙니다. 그것은 희망적으로 합리적으로 명확하고 교육적인 것입니다. :)

0

나는 객관적인 C 모르지만 이것은 내가 C.에

펑 (2, INT (LOG2 (수))

이 당신에게 가장 왼쪽으로 1 비트를 제공해야합니다 그것을 할 것입니다 방법입니다 . 값

이 솔루션을 사용하기 전에 아래의 스티븐 캐논의 COMMENT를 참조하십시오

+1

이것은 많은 플랫폼에서 엄청나게 느리고 다른 사람들에게 잘못된 답을 줄 것입니다 (작은 정수의 경우에도'log2' 또는'pow' 함수가 정확하게 반올림된다는 보장이 없습니다 - 그리고 많은 플랫폼에서 그렇지 않습니다.). –

+0

@Stephen Canon -이 문제를 해결하기위한 또 다른 방법을 보여 드리고 싶습니다. 당신은 느린 문제에 맞을지 모르지만 int 형 주조의 전체 아이디어는 분수 부분을 없애고 일단 그렇게하면 pow()가 항상 정수를 반환합니다. 나는 log2와 pow가 문제를 반올림한다는 것을 알고 있지 않다. 그렇다면 결과가 잘못 될 수 있습니다. – naivnomore

+0

'pow (2, someInteger)'가 항상 정수를 반환한다는 보장은 없습니다. 사실, 나는 그것이 불행한 (불행한 사실이지만) 몇 가지 플랫폼을 사용하는 불행을 겪었습니다. –

0

는 최상위 비트 아래의 모든 비트를 지우려면 :.

while (x & (x-1)) x &= x - 1; 
// 01001 => 01000 
,515,

최하위 비트 이상의 모든 비트를 삭제하려면 다음

x &= -x; 
// 01001 => 00001 

는 바이트 유일한 세트 비트 위치를 얻기 위해 : libkern.h에서

position = ((0x56374210>>(((((x)&-(x))*0x17)>>3)&0x1C))&0x07); 
// 01000 => 3 

가 정의 clz 함수가 32 비트 정수에서 선행 0을 계산합니다. 그것은 원시 Objective-C 함수에 가장 가까운 것입니다.int 형의 최상위 비트의 위치를 ​​얻으려면 : 당신이 테이블 조회를 사용하지 않으려면, 내가 31 - __builtin_clz(yourNumber)을 사용

position = 31 - clz(x); 
// 01001 => 3 
2

.

__builtin_clz()은 gcc, llvm-gcc 및 clang (및 다른 컴파일러도 가능)에서 지원하는 컴파일러 내장 함수입니다. 정수 인수에서 선행 제로 비트의 수를 리턴합니다. 31에서 빼면 가장 높은 순서의 비트 위치가됩니다. 모든 대상 아키텍처에서 비교적 빠른 코드를 생성해야합니다. VC와

관련 문제