Der Tilde-Operator in C.

95

Ich habe den im ELF-Hashing-Algorithmus verwendeten Tilde-Operator gesehen und bin gespannt, was er bewirkt. (Der Code stammt von 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
quelle

Antworten:

127

Der ~Operator ist bitweise NICHT , er invertiert die Bits in eine Binärzahl:

NOT 011100
  = 100011
GWW
quelle
1
Bitweises NICHT ist nützlich für eine Reihe von Dingen, zum Beispiel Bitmasken. Ich bin mir nicht sicher, was Sie unter vorzeichenloser in vorzeichenbehaftete Ganzzahlkonvertierung verstehen.
GWW
2
Warten Sie, sollen Sie nicht UND die Bitmaske? So macht es mein Bitreader, aber es ist empfindlich. Ich habe gelesen, wenn Sie X haben und NICHT, dann subtrahieren Sie eins, erhalten Sie die nicht signierte Version einer signierten Nummer. Ist das nicht korrekt?
MarcusJ
2
Ich verwende bitweise NICHT auf einer Bitmaske in Kombination mit UND, um bestimmte Bits zu löschen, bevor ich sie ändere.
GWW
2
Jemand fragte nach "nicht signierte zu signierte Konvertierung". Die von ausgeführte Operation ~wird auch als "Ein-Komplement" bezeichnet, eine Form der binären Negation. Praktisch alle modernen Computer verwenden die Zweierkomplementarithmetik, die bitweise inverse plus eins. Bei einer vorzeichenbehafteten Ganzzahlvariablen xfinden Sie normalerweise ~x + 1den gleichen Wert wie -x. Zum Beispiel printf("%hx %hx\n", -1234, ~1234 + 1)druckt fb2e fb2eauf meinem Gerät.
Steve Summit
2
@MarcusJ Ja, die Ergänzung funktioniert für die Konvertierung von signierten in nicht signierte (signierte-> nicht signierte). (Beachten Sie jedoch, dass es einfacher ist, den Wert einfach einer anders deklarierten Variablen zuzuweisen und den Compiler darüber zu beunruhigen.) Dies funktioniert jedoch nicht umgekehrt (ohne Vorzeichen -> Vorzeichen), auch weil die möglichen Werte ohne Vorzeichen einen größeren Bereich umfassen Dies kann in eine vorzeichenbehaftete Variable eingepfercht werden, und teilweise, weil dieses Problem nicht genau definiert ist, ohne anzugeben, welches Zeichen zu erfinden ist. Ihre beiden Kommentare haben unterschiedliche Antworten erhalten, da sie entgegengesetzte Richtungen angeben.
Chuck Kollars
43

~ist der bitweise NICHT-Operator. Es invertiert die Bits des Operanden.

Zum Beispiel, wenn Sie haben:

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

Dies ist der bitweise NICHT-Operator. Es werden alle Bits in einer Zahl umgedreht: 100110 -> 011001

unsterblich
quelle
8

Das Tilde-Zeichen wird als Operator verwendet, um alle Bits einer Ganzzahl zu invertieren (bitweise NICHT).

Zum Beispiel : ~0x0044 = 0xFFBB.

Cedekasme
quelle
7

Es ist der bitweise NICHT-Operator. Es invertiert alle Bits in einem ganzzahligen Wert.

Sander De Dycker
quelle
1

Der Tilde-Operator (~), auch bitweiser NOT-Operator genannt, führt das Komplement einer beliebigen Binärzahl als Argument aus. Wenn der Operand auf NOT eine Dezimalzahl ist, konvertiert er ihn als binär und führt die eigene Komplementoperation aus.

Um das eigene Komplement zu berechnen, invertieren Sie einfach alle Ziffern [0 -> 1] und [1 -> 0]. Beispiel: 0101 = 5; ~ (0101) = 1010. Verwendung des Tilde-Operators: 1. Wird beim Maskierungsvorgang verwendet. Maskierung bedeutet das Einstellen und Zurücksetzen der Werte in einem beliebigen Register. zum Beispiel:

char mask ;
mask = 1 << 5 ;

Die Maske wird auf einen Binärwert von 10000 gesetzt, und diese Maske kann verwendet werden, um den in einer anderen Variablen vorhandenen Bitwert zu überprüfen.

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

Dies wird als Maskierung von Bits bezeichnet. 2.Um das binäre Äquivalent einer beliebigen Zahl mithilfe der Maskierungseigenschaften zu ermitteln.

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

Ausgabe: Dezimal 10 entspricht 00001010

Meine Beobachtung : Für den maximalen Bereich eines Datentyps liefert das eigene Komplement den um 1 verringerten negativen Wert auf einen entsprechenden Wert. Beispiel:
~ 1 --------> -2
~ 2 ---------> -3
und so weiter ... Ich werde Ihnen diese Beobachtung mit einem kleinen Code-Snippet zeigen

#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

Hinweis: Dies gilt nur für den Bereich des Datentyps. Mittel für den Datentyp int Diese Regel gilt nur für den Wert des Bereichs [-2.147.483.648 bis 2.147.483.647].
Danke ..... Möge das dir helfen

Günstling
quelle