2009-06-04 17 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

この+ Jian Linの回答は素晴らしいです –

1

これらはビット演算子であるです。 < <と>>シフトビットがそれぞれ左右にあります。 '&'はAND演算子は単一のアンパサンドです。 2ビットのANDをとると、結果は両方のビットが1の場合は1になりますが、ビットの両方またはいずれかが0の場合は0になります。両方のビットが1に等しくなるように両方のビットを設定する必要があります。

私は様々なBit Twiddlingのチュートリアルを書いています。

2

c >> 1は、変数cを1ビット右にシフトすることを意味します。実際には2で割るのと同じです。 '&'は、特定のビットが設定されているかどうかをテストするビット演算子です。 n & 1を実行すると、n & 0x0001と同じで、変数の最下位ビットが設定されているかどうかがチェックされます。それ以外の場合はfalseを設定するとtrueになります。

+0

c >> 1は右シフトです。 c << 1は左シフトです。 – Eric

+0

ありがとうエリック、私はそれを投稿し、私の答えを編集するとすぐにそれに気づいた。 – Naveen

+1

'c >> 1'は、符号なしの型または正の値に対してのみ2で除算されます。負の値の場合、2で割ることは必ずしも同等ではありません。 –

2

c>>1は、Cのビットを "右"にシフトします。これは、符号なしまたは正の整数に対して2で整数除算を行うことと同じになります。すなわち5/2 = 2 == 0101 >> 1 = 0010

n&1

バイナリとを行う奇数のLSB 1及び偶数有するので、数が奇数であるか否かをチェックされるif (n&1)nと1との間しないでください。

このような "トリック"はかわいいですし、一般的にはほとんど価値がありません(コンパイラはこれらの種類のトリックを実行する必要があるため)。このような「トリック」は、ソースコードを読みやすく、デバッグを難しくしてしまいます。

+0

彼らは物事を読みにくくすることに同意しましたが、パフォーマンス上の利点は状況によっては価値があります。 – dmo

+0

パフォーマンスの向上はごくわずかであり、コンパイラはこれを実行します(少なくとも行う必要があります)。プログラミング競争(ACMのものに言えば)の問題の大部分は、正しい解決策のための十分な時間制限を超えています。このようなトリックは、c/2と同じように符号負の整数の場合、c >> 2 breaksのような問題も隠蔽します。 – freespace

+0

ビットシフトは最適化されますが、ビットマスクは最適化されません。また、すべてのケースでパフォーマンスの向上は無視できません。ビットネットワークを使用できない場合、IPネットワーキングは非常に遅くなります。 – dmo

0

他の回答で述べたように、これらはビット演算子です。彼らは非常に "ハードウェアに近い"操作であるため、慣れていないかもしれません。彼らはコンピュータが数値(バイナリ)を格納する特定の方法に縛られているので、標準的な数学のクラスでは教えられません。彼らがプログラマにさらされている理由は、彼らが非常にハードウェアであることです。そのため、いくつかのアルゴリズムは、その使用に伴って大幅に最適化することができます。

0

>>は、符号付きの型(char型、short型、long型、またはlong型のいずれか)の動作が、符号付き型よりも異なります。どちらの場合も右シフトしますが、符号なしの型の場合は左の "新しい"ビットはすべて0ですが、符号付きの型の場合は元の上位ビットの値に応じて0または1になります。そう署名された文字:

1011 0101 

ダウン1シフトこれは、分周パワーの-2動作とが一致することができる

1101 1010 

なります。 -75/2 = -37.5、-38に切り下げられます。

1

これらの演算子は、奇数と偶数の比較に使用されます。

任意の奇数の最下位ビットが常に1である(すなわち)010(1)

もしそうであれば、デフォルトで(Oddnumber & 1)= 1、(evennumber & 1 = 0)。

関連する問題