Operator tilde di C

95

Saya telah melihat operator tilde yang digunakan dalam algoritma hashing ELF, dan saya penasaran apa fungsinya. (Kode ini dari 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;
}
Paul Manta
sumber

Jawaban:

127

The ~operator adalah bitwise NOT , itu membalikkan bit dalam bilangan biner:

NOT 011100
  = 100011
GWW
sumber
1
Bitwise NOT berguna untuk beberapa hal, misalnya, bit mask. Saya tidak yakin apa yang Anda maksud dengan unsigned to signed integer conversion.
GWW
2
Tunggu, bukankah Anda seharusnya DAN bitmask? begitulah cara pembaca bit saya melakukannya, tetapi ini sensitif. Saya membaca bahwa jika Anda memiliki X dan BUKAN, maka kurangi satu Anda akan mendapatkan versi unsigned dari nomor yang ditandatangani, bukankah itu benar?
MarcusJ
2
Saya menggunakan bitwise NOT pada bitmask dalam kombinasi dengan AND untuk menghapus bit tertentu sebelum mengubahnya.
GWW
2
Seseorang bertanya tentang "konversi unsigned to signed". Operasi yang dilakukan oleh ~juga disebut "komplemen satu", yang merupakan salah satu bentuk negasi biner. Hampir semua komputer modern menggunakan aritmatika komplemen dua, yang merupakan kebalikan bitwise, ditambah satu. Jadi untuk variabel integer bertanda x, Anda biasanya akan menemukan yang ~x + 1memberikan nilai yang sama dengan -x. Misalnya, printf("%hx %hx\n", -1234, ~1234 + 1)mencetak fb2e fb2edi mesin saya.
Steve Summit
2
@MarcusJ Ya, pelengkap seseorang berfungsi untuk mengkonversi ditandatangani ke unsigned (ditandatangani-> unsigned). (Perhatikan meskipun lebih mudah untuk hanya menetapkan nilai ke variabel yang dideklarasikan secara berbeda dan biarkan kompilator khawatir tentang itu.) Tetapi itu tidak bekerja sebaliknya (unsigned-> signed), sebagian karena kemungkinan nilai unsigned menjangkau rentang yang lebih luas than dapat dijejalkan ke dalam variabel bertanda, dan sebagian karena masalah itu tidak terdefinisi dengan baik tanpa menentukan -dari informasi luar mungkin- tanda apa yang harus ditemukan. Kedua komentar Anda mendapat balasan yang berbeda karena menentukan arah yang berlawanan.
Chuck Kollars
43

~adalah operator bitwise NOT. Ini membalikkan bit operan.

Misalnya, jika Anda memiliki:

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

Ini adalah operator NOT bitwise. Ini membalik semua bit dalam angka: 100110 -> 000011

abadi
sumber
8

Karakter tilde digunakan sebagai operator untuk membalikkan semua bit integer (bitwise NOT).

Sebagai contoh: ~0x0044 = 0xFFBB.

Cedekasme
sumber
7

Ini adalah operator NOT bitwise. Ini membalikkan semua bit dalam nilai integer.

Sander De Dycker
sumber
1

Operator Tilde (~) juga disebut operator bitwise NOT, melakukan pelengkap seseorang atas bilangan biner sebagai argumen. Jika operan ke NOT adalah bilangan desimal maka ia mengubahnya sebagai biner dan melakukan operasi komplemen satu.

Untuk menghitung komplemen seseorang, cukup balikkan semua digit [0 -> 1] dan [1 -> 0] Ex: 0101 = 5; ~ (0101) = 1010. Penggunaan operator tilde: 1. Digunakan dalam operasi masking, Masking berarti mengatur dan mereset nilai di dalam register manapun. misalnya:

char mask ;
mask = 1 << 5 ;

Ini akan mengatur mask ke nilai biner 10000 dan mask ini dapat digunakan untuk memeriksa nilai bit yang ada di dalam variabel lain.

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

Ini disebut Masking bit. 2. Untuk menemukan padanan biner dari bilangan apa pun menggunakan properti masking

#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");
  }  
}

Output: Desimal 10 sama dengan 00001010

Pengamatan saya : Untuk rentang maksimum dari semua tipe data, pelengkap satu memberikan nilai negatif yang diturunkan 1 ke nilai yang sesuai. mis .:
~ 1 --------> -2
~ 2 ---------> -3
dan seterusnya ... Saya akan tunjukkan observasi ini menggunakan potongan kode kecil

#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

Catatan: Ini hanya berlaku untuk rentang tipe data. artinya untuk tipe data int aturan ini hanya akan berlaku untuk nilai range [-2,147,483,648 hingga 2,147,483,647].
Terima kasih ..... Semoga ini membantu Anda

Antek
sumber