2009-06-04 3 views
2

나는 "Programming Challenges : Programming Contest Training Manual"이라는 책을 읽으며, 나는 연산자 C >> 1과 비교를 통해 (n & 1) 누군가의 도움을받을 수없는 문제를 구현하고있다. 그들이 의미하는지 알기 위해서? C 연산자는 무엇을 의미합니까?

는 사람들은 비트 연산자있는 예제 코드

#include <stdio.h> 

#define MAX_N 300 
#define MAX_D 150 

long cache[MAX_N/2][2]; 

void make_cache(int n,int d,int mode) 
{ 
    long tmp[MAX_D]; 
    int i,count; 

    for(i=0;i<MAX_D;i++) tmp[i]=0; 

    tmp[0]=1;count=0; 

    while(count<=n) 
    { 
     count++; 

     for(i=(count&1);i<=d;i+=2) 
     { 
      if(i) 
       tmp[i] = tmp[i-1] + tmp[i+1]; 
      else if(!mode) 
       tmp[0]=tmp[1]; 
      else 
       tmp[0]=0; 
     } 

     if((count&1)==(d&1)) 
      cache[count>>1][mode]=tmp[d]; 
    } 
} 

int main() 
{ 
    int n,d,i; 
    long sum; 

    while(1) 
    { 
     scanf("%d %d",&n,&d); 

     if(n&1) 
      sum=0; 
     else if(d==1) 
      sum=1; 
     else if(n<(d<<1)) 
      sum=0; 
     else if(n==(d<<1)) 
      sum=1; 
     else 
     { 
      make_cache(n,d,0); 
      make_cache(n,d,1); 
      sum=0; 

      for(i=0;i<=(n>>1);i++) 
       sum+=cache[i][0]*cache[(n>>1)-i][1]; 
     } 

     printf("%ld\n",sum); 
    } 

    return 0; 
} 

답변

15

>> 비트를 오른쪽 n 비트 수만큼 이동합니다. 그래서이 :

1011 0101 

아래 1 이동됩니다 :

0101 1010 

& 운영자가 걸릴 그래서 다시, 비트 단위을 수행하고 :

1011 0101 

& 1로 당신이 얻을 (모두를 의미합니다 1이어야합니다. 그렇지 않으면 0입니다.)

1011 0101 
&0000 0001 
---------- 
0000 0001 

잘하면이 답변을 귀하의 질문에 도움이됩니다!

+0

this + Jian Lin 대답은 우수합니다. –

1

입니다. < < 및 >> 시프트 비트가 각각 왼쪽 및 오른쪽입니다. '&'은 AND 연산자가 하나의 앰퍼샌드입니다. 당신이 두 비트를 AND 할 때 두 비트가 모두 1이면 결과는 1이지만 두 비트 또는 두 비트 중 하나가 0이면 결과는 0입니다. 좋은 생각은 두 비트가이 값을 1로 설정해야한다는 것입니다.

다양한 Bit Twiddling에 대한 자습서를 작성했습니다.

2

c >> 1은 변수 c를 1 비트 오른쪽으로 이동하는 것을 의미합니다. 이는 실제로 2를 나누는 것과 같습니다. '&'은 특정 비트가 설정되었는지 여부를 테스트하는 데 사용되는 비트 AND 연산자입니다. n & 1을 수행하면 n & 0x0001과 같아 변수의 최하위 비트가 설정되었는지 여부를 확인합니다. 그렇지 않으면 false를 설정하면 true가됩니다.

+0

c >> 1은 오른쪽 시프트입니다. c << 1은 왼쪽 쉬프트입니다. – Eric

+0

감사합니다. Eric, 게시하고 답변을 수정하자마자 바로 언급했습니다. – Naveen

+1

'c >> 1'은 부호없는 유형 또는 양수 값에 대해서만 2로 나눕니다. 음수 값의 경우 2로 나누는 것이 반드시 동일한 것은 아닙니다. –

2

c>>1은 C의 비트를 부호없는 또는 양의 정수로 2로 정수 나누기를 수행하는 것과 같은 결과를 나타내는 "오른쪽"으로 이동합니다. 즉 5/2 = 2 == 0101 >> 1 = 0010

n&1 이진 AND를 수행 홀수 LSB가 1과 짝수 가지기 때문에, 개수가 홀수인지 여부를 확인한다 if (n&1)n 1 사이 하지마.

"트릭"은 귀엽고 일반적으로 (컴파일러가 이런 종류의 트릭을 수행해야하므로) 일반적으로 가치가 없습니다. 프로그래밍 경쟁에서 쓸데없는 것은 정확한 해결책을 만들어내는 것입니다. 이러한 "트릭"은 소스 코드를 읽기 쉽도록하기 때문에 디버깅을 어렵게 만듭니다.

+0

일을 더 어렵게 만드는 것으로 동의했지만, 상황에 따라 성능상의 이점이 있습니다. – dmo

+0

성능 향상은 무시할 만하며 컴파일러가 자동으로 수행합니다 (또는 적어도 수행해야합니다). 프로그래밍 경쟁 (ACM에 대해 말하기)에서 문제의 대부분은 정확한 해결책을위한 충분한 시간 제한을 가지고 있습니다. 이러한 트릭은 c/2가 아닌 부호있는 네거티브 정수의 경우 c >> 2 breaks와 같은 문제를 숨 깁니다. – freespace

+0

비트 쉬프트는 최적화되지만 비트 마스크는 최적화되지 않을 수 있습니다. 그리고 모든 경우에 성능 향상은 무시할 수 없습니다. IP 네트워킹은 비트 연산을 사용할 수없는 경우 훨씬 느립니다. – dmo

7

c >> 1은 (정수로) 2로 나누어야하며, n & 0x1은 종종 숫자가 홀수인지 여부를 테스트합니다.

는 여기에 몇 가지 기사가 있습니다 : 다른 답변에서 언급 한 바와 같이

http://irc.essex.ac.uk/www.iota-six.co.uk/c/e5_bitwise_shift_operators.asp

http://irc.essex.ac.uk/www.iota-six.co.uk/c/e4_bitwise_operators_and_or_xor.asp

+0

매우 간단하게 설명했다. –

+0

+1은'>>'의 정수 나누기 부분을 간결하게 나타냅니다. – ojrac

0

, 이러한 비트 연산자입니다. 그것들은 매우 "하드웨어에 가까운"조작이기 때문에 익숙하지 않을 수 있습니다. 그것들은 컴퓨터가 수 (바이너리)를 저장하는 특정한 방법에 묶여 있기 때문에 표준 수학 수업에서는 가르치지 않습니다. 프로그래머에게 노출되는 이유는 하드웨어가 빠르기 때문에 매우이므로 일부 알고리즘은 사용에 따라 크게 최적화 될 수 있습니다.

0

>>는 서명 된 유형보다 부호없는 유형 (char, short, long 또는 long long)에 따라 다르게 동작합니다. 두 경우 모두 오른쪽으로 시프트되지만 부호가없는 유형의 경우 왼쪽의 "새"비트는 모두 0이지만 서명 된 유형의 경우 원래의 높은 비트 값에 따라 0 또는 1입니다. 그래서 서명 된 문자 :

1011 0101 

아래 1 이동하게

1101 1010 

이 그것을 일치로 만드는 분주 전력-2 작동; -75/2 = -37.5, -38로 반올림 됨.

1

이 연산자는 홀수 및 짝수 비교에 사용됩니다.

어떤 홀수의 최하위 비트는 항상 하나입니다 (즉) 010 (1)

그렇다면 기본적으로 (Oddnumber & 1) = 1 (evennumber & 1 = 0).

관련 문제