Cのチルダ演算子


95

ELFハッシュアルゴリズムでチルド演算子が使用されているのを見てきましたが、その機能に興味があります。(コードはEternally Confusedからのものです。)

unsigned elf_hash ( void *key, int len )
{
  unsigned char *p = key;
  unsigned h = 0, g;
  int i;

  for ( i = 0; i < len; i++ ) {
    h = ( h << 4 ) + p[i];
    g = h & 0xf0000000L;

    if ( g != 0 )
      h ^= g >> 24;

    h &= ~g;
  }

  return h;
}

回答:


126

~オペレータは、ビット単位でNOTが進数のビットを反転させ、:

NOT 011100
  = 100011

1
ビットごとのNOTは、ビットマスクなど、多くの場合に役立ちます。符号なし整数から符号付き整数への変換の意味がわかりません。
GWW、

2
待って、ビットマスクをANDするつもりはありませんか?それが私のビットリーダーのやり方ですが、とても扱いにくいものです。Xがあり、Xがない場合は、1を減算すると、署名された番号の符号なしバージョンが得られますが、それは正しくありませんか?
MarcusJ 2015年

2
ビットマスクでビットごとのNOTをANDと組み合わせて使用​​して、特定のビットを変更する前にそれらをクリアします。
GWW、2015年

2
「署名されていない署名付き変換」について誰かが尋ねました。によって実行される演算~は、「1の補数」とも呼ばれます。これは、バイナリ否定の1つの形式です。最近のほとんどすべてのコンピュータは、ビット単位の逆数である2の補数演算に1を加えたものを使用しています。したがって、符号付き整数変数の場合x、通常~x + 1はと同じ値を与えることがわかります-x。たとえば、私のマシンでprintf("%hx %hx\n", -1234, ~1234 + 1)印刷fb2e fb2eします。
Steve Summit

2
@MarcusJはい、補数は符号付きから符号なしに変換するために機能します(signed-> unsigned)。(ただし、別の方法で宣言された変数に値を割り当てて、コンパイラーにそれを心配させるほうが簡単です。)しかし、符号なしの可能性のある値がより広い範囲に及ぶため、逆に(符号なし->符号付き)は機能しませ。署名された変数に詰め込むことができるよりも、その理由の1つは、外部の情報から-発明する署名を指定しないと問題が明確に定義されないためです。2つのコメントは反対の方向を指定しているため、返信が異なります。
チャックコラーズ2016年

43

~ビットごとのNOT演算子です。オペランドのビットを反転します。

たとえば、次の場合:

char b = 0xF0;  /* Bits are 11110000 */
char c = ~b;    /* Bits are 00001111 */

12

これはビットごとのNOT演算子です。数値のすべてのビットを反転します:100110-> 011001


8

チルダ文字は、整数のすべてのビットを反転する演算子(ビットごとのNOT)として使用されます。

次に例を示します~0x0044 = 0xFFBB



1

チルダ演算子(〜)はビット単位のNOT演算子と呼ばれ、任意の2進数の1の補数を引数として実行します。NOTのオペランドが10進数の場合は、それを2進数に変換し、1の補数演算を実行します。

1の補数を計算するには、単純にすべての数字[0-> 1]と[1-> 0]を反転します。例:0101 = 5; 〜(0101)=1010。チルダ演算子の使用:1.これはマスキング操作で使用されます。マスキングは、任意のレジスタ内の値を設定およびリセットすることを意味します。例:

char mask ;
mask = 1 << 5 ;

これはマスクを10000のバイナリ値に設定し、このマスクを使用して他の変数内に存在するビット値をチェックできます。

int a = 4;
int k = a&mask ; if the 5th bit is 1 , then k=1 otherwise k=0. 

これはビットのマスキングと呼ばれます。2.マスキングプロパティを使用して、任意の数値に相当するバイナリを検索します。

#include<stdio.h>
void equi_bits(unsigned char);
int main()
{
    unsigned char num = 10 ;
    printf("\nDecimal %d is same as binary ", num);
    equi_bits(num);
    return 0; 
} 
void equi_bits(unsigned char n)
{
  int i ; 
  unsigned char j , k ,mask ;
  for( i = 7 ; i >= 0 ; i--)
  {
     j=i;
     mask = 1 << j;
     k = n&mask ; // Masking
     k==0?printf("0"):printf("1");
  }  
}

出力:10進数の10は00001010と同じ

私の観察:任意のデータ型の最大範囲について、1の補数は、対応する値に1を引いた負の値を提供します。例:
〜1 --------> -2〜2
---------> -3
など...少しコードスニペットを使用して、この観察結果を示します

#include<stdio.h>
int main()
{
    int a , b;
    a=10;
    b=~a; // b-----> -11    
    printf("%d\n",a+~b+1);// equivalent to a-b
    return 0;
}
Output: 0

注:これは、データ型の範囲に対してのみ有効です。intデータ型の場合、このルールはrange [-2,147,483,648〜2,147,483,647]の値にのみ適用されます。
ありがとう.....これがあなたを助けますように

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.