Bits in einem Integer vertauschen
-
Das ist doch korrekt so, oder?
-
ach so, ich wußte nicht, was dir genau unklar ist oder war. Vielleicht noch einmal zur Klärung (ich habe Verständnis-Probleme damit, daß du schreibst
Raptor schrieb:
Die Bitoperatoren returnen also true, falls das Bit erfolgreich geaendert wurde und false, wenn das angegebene Bit schon den zu aenderden Typ hat.
)
( x & mask1) und (x & mask2) geben nur dann 'true' zurück, wenn das Bit an der entsprechenden Stelle gesetzt ist, sonst 'false'.
Geändert wird nur hier (wenn die jeweilige Bedingung erfüllt ist):
newx |= mask2; newx |= mask1;
nachdem in der Zeile
newx = x & ~(mask1 | mask2);
der Wert des übergebenen integers schon einmal (vorbereitend) modifiziert wurde.
Oder habe ich deine Nachfrage damit noch nicht ausreichend beantwortet?
MfG
-
@Raptor
Mir scheint, du solltest dich erst mal mit der Theorie von logischen und Bitoperatoren befassen bevor du versuchst den Code zu verstehen.
Bitoperatoren haben als Ergebnis weder false noch true, sondern die entsprechende Verknüpfung der Operanden. Nur logische Operatoren liefern false bzw. true.
Ausserdem, wtf sollen Bits für zu ändernde Typen haben?
-
Bitoperatoren haben als Ergebnis weder false noch true, sondern die entsprechende Verknüpfung der Operanden. Nur logische Operatoren liefern false bzw. true.
Wenn ich mit if abfragen kann, ob die gewuenschte Operation erfolgreich war, dann muss entweder true oder false zurueckgegeben werden.
-
Raptor schrieb:
Wenn ich mit if abfragen kann, ob die gewuenschte Operation erfolgreich war, dann muss entweder true oder false zurueckgegeben werden.
die gewünschte operation ist aber immer erfolgreich
a&b
verknüpft a und b bitweise
das ergebnis ist die verknüpgung der beiden.das kann zB auch 0 sein wenn du zB
0100
mit
0011verknüpfst - denn da kommt
0000
raus
-
die gewünschte operation ist aber immer erfolgreich
Also nachdem was Probe-Nutzer gesagt hat, kann das aber nicht sein.
( x & mask1) und (x & mask2) geben nur dann 'true' zurück, wenn das Bit an der entsprechenden Stelle gesetzt ist, sonst 'false'.
und
so daß bei nichtgesetzten Bits überhaupt keine Bit-Oder-Verknüpfung stattfindet (das Ergebnis stimmt aber trotzdem immer, wegen der oben angegebenen Zeile muß nicht dafür gesorgt werden, daß die Bits an den Tauschpositionen Null gesetzt werden müssen, wenn die if-Bedingungen nicht erfüllt sind)
Ich habe es jetzt so aufgefasst, dass z.B.
beiif( x & mask1 ) newx |= mask2; if( x & mask2 ) newx |= mask1;
Wenn in der if-Bedingung (in diesem speziellen Fall) das Bit nicht gesetzt werden konnte, oder generell ein einziges Bit nicht gesetzt werden konnte(weil es schon gesetzt war) false returnes wird. Sonst true.
-
die gewünschte operation ist aber immer erfolgreich
Also nachdem was Probe-Nutzer gesagt hat, kann das aber nicht sein.
( x & mask1) und (x & mask2) geben nur dann 'true' zurück, wenn das Bit an der entsprechenden Stelle gesetzt ist, sonst 'false'.
und
so daß bei nichtgesetzten Bits überhaupt keine Bit-Oder-Verknüpfung stattfindet (das Ergebnis stimmt aber trotzdem immer, wegen der oben angegebenen Zeile muß nicht dafür gesorgt werden, daß die Bits an den Tauschpositionen Null gesetzt werden müssen, wenn die if-Bedingungen nicht erfüllt sind)
Ich habe es jetzt so aufgefasst, dass z.B.
beiif( x & mask1 ) newx |= mask2; if( x & mask2 ) newx |= mask1;
Wenn in der if-Bedingung (in diesem speziellen Fall) das Bit nicht gesetzt werden konnte, oder generell ein einziges Bit nicht gesetzt werden konnte(weil es schon gesetzt war) false returnes wird. Sonst true.
-
ich versuche noch einmal, zu erklären, was passiert (und was nicht):
Raptor schrieb:
Ich habe es jetzt so aufgefasst, dass z.B.
beiif( x & mask1 ) newx |= mask2; if( x & mask2 ) newx |= mask1;
Wenn in der if-Bedingung (in diesem speziellen Fall) das Bit nicht gesetzt werden konnte, oder generell ein einziges Bit nicht gesetzt werden konnte(weil es schon gesetzt war) false returnes wird. Sonst true.
verstehe ich dich richtig, daß du annimmst, daß
x & mask1 bzw. x & mask2
ein Bit setzen oder löschen? Das ist nicht der Fall, hier wird nur geprüft, ob ein bestimmtes Bit (und zwar jenes, welches in mask1 bzw. mask2 gesetzt ist) in x gesetzt ist (dann ist die Bedingung erfüllt, da jeder von Null verschiedene Wert, als logischer Ausdruck gewertet, als 'true' bewertet wird), und nichts geändert. Gesetzt werden die Bits nur durch die folgenden Anweisungen hier:
newx |= mask2; bzw. hier: newx |= mask1;
MfG
-
verstehe ich dich richtig, daß du annimmst, daß
x & mask1 bzw. x & mask2
ein Bit setzen oder löschen?
Ja genau das meinte ich.
Der Operator& loescht ein Bit, das in der Maske 0 ist.
Der Operator| setzt ein Bit, das in der Maske 1 ist.Das ist nicht der Fall
Was?hier wird nur geprüft, ob ein bestimmtes Bit (und zwar jenes, welches in mask1 bzw. mask2 gesetzt ist) in x gesetzt ist
Geprueft?? Aber die Operation wird doch durchgefuehrt,also das Bit gesetzt, oder geloescht.
z.B.if(cin >> x)
Da wird doch auch nicht geprueft, ob ein cin moeglich waere, sondern es wird einfach gemacht.
Ich versteh im Moment nicht ganz.
Trotzdem vielen Dank fuer deine Hilfe.MfG
-
ich habe das wohl etwas mißverständlich ausgedrückt: es wird die Variable x in den Ausdrücken
x & mask1 bzw. x & mask2
nicht geändert, und ich nahm an, daß du eine Änderung von x erwartet hattest (natürlich wird ein Ausdruck berechnet, nämlich der Wert des Ausdrucks (x & mask1), und natürlich sind im resultierenden Wert alle Bits gelöscht, an denen in mask1/mask2 ein Null-Bit steht)! Es wird also lediglich die Bit-Und-Verknüpfung ausgeführt, und wenn eben dann ein gesetztes Bit "übrig" bleibt, dann ist die Bedingung erfüllt (wie ich oben erklärt habe). Deshalb ist aber noch lange nichts in der Variablen x oder newx (das ja das Ergebnis aufnimmt) geändert worden, das passiert erst mit den Bit-Oder-Verknüpfungen. Anschließend wird also nur das Ergebnis der Bit-Und-Verknüpfung geprüft, nichts anderes meinte ich mit allen Antworten, ich hoffe, es ist damit klargestellt worden, wie ich das meinte. Und dann müßte doch geklärt sein, wie dieser Bit-Tausch funktioniert (er wird nur über die Bit-Oder-Operationen durchgeführt)
MfG
-
Raptor schrieb:
Ich versteh im Moment nicht ganz
Genau deshalb solltest du dich erst mal mit der Theorie befassen.
Vielleicht wirds ja klarer, wenn du das mal mit den normalen arithmetischen Operatoren vergleichst, denn die arbeiten auf die gleiche Weise.
a = b + c; a = b & c;
Welche Variablen werden hier verändert, welche nicht?
Und was passiert nun, wenn ich die Zuweisung einfach weglasse?
b + c; b & c;
-
Ok. Habs jetzt gerafft.Natuerlich wird mit
x&mask
nichts veraendert.
Sonst muesste es jax&=mask
heissen.
Ich hab den Wald vor lauter Baeumen nicht gesehen. Sry.
Eine Frage hab ich jetzt aber doch noch.
Was passiert genau in der if Abfrage?MfG
Raptor
-
Raptor schrieb:
Was passiert genau in der if Abfrage?
Welche meinst du?
Also in der erstenif( bitnr1 < 0 || bitnr1 > msb || bitnr2 < 0 || bitnr2 > msb) return x; // Zurueck, falls ungueltige Bit-Nr.
werden die Parameter lediglich auf sinnvolle Werte geprüft. Das ist imo nutzlos, denn wenn ich mir den Algo anschau wird dann so oder so der Wert von x zurückgegeben.
In den nächsten beidenif( x & mask1 ) newx |= mask2; // Bits tauschen if( x & mask2 ) newx |= mask1;
passieren eigentlich zwei Dinge. Erstens wird eine Und-Verknüpfung von x und mask1 bzw. mask2 durchgeführt. Da der Compiler im if-statement aber einen boolschen Wert braucht, wird zweitens das Verknüpfungsergenis dann noch umgewandelt. Da bei Bitoperatoren eh nur Integer verwendet werden können, ist das relativ einfach. Ein Wert gleich 0 liefert false, alles ungleich 0 true.
Man könnte theoretisch auch folgendes schreiben:if ((x & mask1) != 0) newx |= mask2;