Bitweise NOT ~

Der Bitweise-NOT-Operator wandelt alle Bits eines Integer-Wertes in ihr Gegenteil um: Aus 0 wird 1 und umgekehrt. Dies entspricht dem sogenannten Einerkomplement.












01001001100101100000001011010010
10110110011010011111110100101101
#include <stdio.h>

void printbinary(int x){
  char str[33]; str[32] = '\0';
  int i = 32;
  while(i){i--; str[i] = (x & 1) + '0'; x>>=1;}
  printf("%s\n", str);
}

int main(){
  int x = 1234567890;
  printbinary( x);
  printbinary(~x);
  return 0;
}

Siehe auch Logisch-NOT-Operator !, Bitweise-AND-Operator &, Bitweise-OR-Operator |, Bitweise-XOR-Operator ^

Details

Der Bitweise-NOT-Operator erwartet einen Operanden als rvalue und wird von rechts nach links abgearbeitet. Der Rückgabewert ist ein rvalue, der stets ein Integer-Typ ist.

Der Bitweise-NOT-Operator ist nur für Integer-Werte zulässig. Unter C++ ist zusätzlich auch die Anwendung des Operators auf boolsche Werte erlaubt, welche jedoch vor Anwendung des Operators in einen int umgewandelt werden.

Der Unterschied zwischen der bitweisen und der logischen Variante des NOT-Operators ist für Einsteiger in die Sprache manchmal schwer verständlich. Der Unterschied ist: Die bitweise Variante verändert alle Bits von Werten, die logische Variante verändert 1-Bit-Werte. Selbst bei erfahrenen Programmierern kommt es vor, dass man aufgrund der ähnlichen Schreibweise (~ oder !) aus Versehen und ohne es zu merken den falschen Operatoren verwendet. Da zudem in gewissen Fällen (beispielsweise bei der Anwendung des Operators auf den Wert -1) die beiden Operatoren dieselben Ergebnisse liefern, ist dies eine schwer aufzufindende Fehlerquelle, die manchmal einige Stunden Fehlersuche benötigt.

Der Bitweise-NOT-Operator wird häufig für Masken verwendet.

Überladen des Operators

Der Bitweise-NOT-Operator hat grundsätzlich die semantische Bedeutung einer komponentenweisen boolschen Verneinung. Die Überladung des Operators wird auch allgemein verwendet, wenn ein Objekt zwei Zustände bezeichnet, zwischen denen hin und her gewechselt werden soll. Allerdings ist auch jegliche andere Semantik vom Programmierer definierbar. Trotzdem sei angemerkt, dass der Bitweise-NOT-Operator nur selten überladen wird

Die Prototypen für das Überladen des Bitweise-NOT-Operators sind die folgenden (Einschränkungen und Erläuterungen siehe Überladen von Operatoren):

inside class


outside class
Type operator ~();
Type operator ~() const;

Type operator ~(Type);

Im folgenden Beispiel wird eine Klasse präsentiert für eine 2x2 Matrix. Der überladene Bitweise-NOT-Operator gibt hier die Inverse der Matrix zurück.























1.000000, 2.000000
3.000000, 4.000000

-2.000000, 1.000000
1.500000, -0.500000
#include <cstdio>

class Matrix22{
  float a[4];
public:
  Matrix22(float d1, float d2, float d3, float d4){
    a[0]=d1; a[1]=d2; a[2]=d3; a[3]=d4;
  }
  void print(){
    printf("%f, %f\n%f, %f\n",
          a[0], a[1], a[2], a[3]);
  }
  
  Matrix22 operator ~() const {
    float inv = a[0] * a[3] - a[1] * a[2];
    if(inv == 0){return Matrix22(0, 0, 0, 0);}
    inv = 1 / inv;
    return Matrix22( inv * a[3], -inv * a[1],
                    -inv * a[2],  inv * a[0]);
  }
};

int main(){
  Matrix22 m1(1, 2, 3, 4);
    m1 .print();
  (~m1).print();
  return 0;
}