Bit vertauschen
-
Hey, wie kann ich das n-te Bit der Variable a mit dem m-ten Bit der Variable b tauschen?
unsigned char a, b; swapBit(a, 2, b, 4); // bit 3 der variable a mit bit 5 der variable b tauschen.Wie geht das?

-
//ungetestet void swapBit(int a,int posa,int b,int posb){ int bitmaska=1<<posa; int bitmaskb=1<<posb; int bita=(a&bitmaska)>>posa; int bitb=(b&bitmaska)>>posb; a&=~bitmaska; b&=~bitmaskb; a|=bitb<<posa; b|=bita<<posb; }Ich würde anraten, nochmal zu testen, ob der a=b=a^=b-Trick hier verwertbar ist.
So ungefähr//nur geraten a^=((b>>posb)&1)<<posa; b^=((a>>posa)&1)<<posb; b^=((a>>posa)&1)<<posb; //nicht hübsch
-
Ungetestet:
void swapBit(int& var1, size_t pos1, int& var2, size_t pos2) { int temp = var1; var1 &= ~(0x01 << pos1); var1 |= ((var2 >> pos2) & 0x01) << pos1; var2 &= ~(0x01 << pos2); var2 |= ((temp >> pos1) & 0x01) << pos2; }edit: Dabei wird aber von rechts, beginnend mit 0 gezählt.
-
wx++ schrieb:
Ungetestet:
void swapBit(int& var1, size_t pos1, int& var2, size_t pos2) { int temp = var1; var1 &= ~(0x01 << pos1); var1 |= ((var2 >> pos2) & 0x01) << pos1; var2 &= ~(0x01 << pos2); var2 |= ((temp >> pos1) & 0x01) << pos2; }edit: Dabei wird aber von rechts, beginnend mit 0 gezählt.
Ich habe es mal so getestet (für
unsigned charumgeschrieben):unsigned char bla = 100; std::cout << "= " << bla << std::endl; swapBit(bla, 8-1, bla, 8-2); std::cout << "swap => " << bla << std::endl; swapBit(bla, 8-2, bla, 8-1); std::cout << "= " << bla << std::endl;Scheint zu klappen
Danke 
volkard schrieb:
//ungetestet void swapBit(int a,int posa,int b,int posb){ int bitmaska=1<<posa; int bitmaskb=1<<posb; int bita=(a&bitmaska)>>posa; int bitb=(b&bitmaska)>>posb; a&=~bitmaska; b&=~bitmaskb; a|=bitb<<posa; b|=bita<<posb; }Ich würde anraten, nochmal zu testen, ob der a=b=a^=b-Trick hier verwertbar ist.
So ungefähr//nur geraten a^=((b>>posb)&1)<<posa; b^=((a>>posa)&1)<<posb; b^=((a>>posa)&1)<<posb; //nicht hübschAuch deine Codes habe ich auf diese Weise getestet.
Es kommt aber am Ende nicht mehr das gleiche Ergebnis raus. Es scheint also etwas schief zu laufen.
-
Zulooo schrieb:
Hey, wie kann ich das n-te Bit der Variable a mit dem m-ten Bit der Variable b tauschen?
...
Wie geht das?
Wenn die zu tauschenden Bits gleich sind, braucht man sie nicht zu tauschen, stimmt's ?
Sind diese Bits ungleich, toggelt man sie und fertig!void swapBit(int& var1, size_t pos1, int& var2, size_t pos2) { if (((var1 >> pos1) & 1) != ((var2 >> pos2) & 1)) { var1 ^= (1 << pos1); var2 ^= (1 << pos2); } }
-
So?
static inline int swapBit( int value, int i, int j ) { int swap = ( ( value >> i ) ^ ( value >> j ) ) & 1; return value ^ ( ( swap << i ) | ( swap << j ) ); }
-
David_pb schrieb:
So?
static inline int swapBit( int value, int i, int j ) { int swap = ( ( value >> i ) ^ ( value >> j ) ) & 1; return value ^ ( ( swap << i ) | ( swap << j ) ); }So:
static inline int swapBit( int value, int i, int j ) { if (((value >> i) & 1) != ((value >> j) & 1)) value ^= ((1 << i) | (1 << j)); return value; }
-
otto8 schrieb:
So:
static inline int swapBit( int value, int i, int j ) { if (((value >> i) & 1) != ((value >> j) & 1)) value ^= ((1 << i) | (1 << j)); return value; }
Auf keinen Fall!
So:static inline int swap( int value, int i, int j ) { return ( ( ( value >> i ) ^ ( value >> j ) ) & 1 ) ? value ^ ( ( 1 << i ) | ( 1 << j ) ) : value; }
-
Eine Offtopic-Frage: Ist Code, der nach jedem Token ein Leerzeichen verwendet, wirklich so viel leserlicher als Code, der durchgehend ohne Leerzeichen auskommt?

-
Nexus schrieb:
Eine Offtopic-Frage: Ist Code, der nach jedem Token ein Leerzeichen verwendet, wirklich so viel leserlicher als Code, der durchgehend ohne Leerzeichen auskommt?

Sharp oder IBM?
Manche machen auch nach jeder Zeile eine Leerzeile, außer da, wo ich statt der zwei zusammegehörenden Zeilen lieber bloß eine geschrieben hätte.
-
Nexus schrieb:
Eine Offtopic-Frage: Ist Code, der nach jedem Token ein Leerzeichen verwendet, wirklich so viel leserlicher als Code, der durchgehend ohne Leerzeichen auskommt?

Ich finde oftmals ja. In einer Situation, wie oben muss man den Ausdruck eh recht genau anschauen, wenn man mit den Klammern nicht durcheinander kommen will, aber ich mache auch gerne Abstände, damit ich den Code nicht lesen, sondern nur anschauen muss. Wenn jetzt alles zusammen klebt übersehe ich leicht eine Klammer oder ein Zeichen o.ä.
Ich grupiere auch gerne Anweisungen, wie volkard anspricht. Jetzt nicht prinzipiell nach jeder Zeile ein Abstand, aber wenn ich 3-4 Aufrufe z.B auf das gleiche Objekt habe, dann kommen die nache zu einander, Leerzeile und das anderere Anweisungen.
foo.f (); foo.bar (); foo.foobar (); baz.foo (); baz.bar ();
-
Natürlich ist es sinnvoll, Abstände zu benutzen. In meinen Augen tragen Whitespaces jedoch besonders dann zur Übersicht bei, wenn man sie unterschiedlich stark einsetzt.
(7*x - 3*y + 5) / (4*x + 5*y - 8)Anweisungen zeilenweise gruppieren tue ich auch. Aber eben, auf diese Weise werden Newlines wieder mit Mass verwendet.
-
drakon schrieb:
foo.f (); foo.bar (); foo.foobar (); baz.foo (); baz.bar ();da könntest doch auch schon fast über chaining nachdenken
foo.f().bar().foobar(); baz.foo().bar();evtl. gehts auch nur so
foo->f()->bar()->foobar(); baz->foo()->bar();
-
Es ginge schon beides, abhängig davon, ob eine Referenz oder ein Zeiger zurückgegeben würde.
Chaining ist im Grunde genommen eine interessante Technik, aber in vielen Fällen macht sie den Code nur noch unübersichtlicher. Denn weniger Zeilen ist nicht unbedingt besser.
image.set_size(22, 13).set_background_color(color::green).set_rotation(15.5f); // vs. image.set_size(22, 13) image.set_background_color(color::green) image.set_rotation(15.5f);
-
Test:
z = (7*x - 3*y + 5) / (4*x + 5*y - 8)z = (7*x-3*y+5) / (4*x+5*y-8)z=(7*x-3*y+5)/(4*x+5*y-8)z= (7*x - 3*y + 5) / (4*x + 5*y - 8)
-
also den größten flächeninhalt hat das letzte

-
Kompromiss?

z = (7*x - 3*y + 5) / (4*x + 5*y - 8);Aber das mache ich eigentlich eher selten. Kommt ja auch nicht allzu häufig vor, dass man Teilausdrücke einander so schön zuordnen kann. Was ich manchmal bei komplexeren Ausdrücken mache:
foo.bar( vector2( 32.5f + random(-4.f, 4.f) - 25.8f*foo.bir(), 66.7f), 124.4f - random(3.f, 7.f)/foo.bor(), "a string");Ich muss allerdings gestehen, dass ich Abstände bei verschiedenen Operatoren nicht immer ganz strikt handhabe. Ich habe diesbezüglich noch kein Optimum gefunden, das man verallgemeinern könnte.
-
foo.bar( vector2( 32.5f+random(-4.f,4.f)-25.8f*foo.bir() ,66.7f ) ,124.4f-random(3.f,7.f)/foo.bor() ,"a string" );
-
Chaining kann man machen, aber das macht imo nur dort Sinn, wo von einer Klasse wirklich ein solchen sehr intensives benutzen von einfachen Funktionen erwartet wird. (Hab das mal bei einer HTML Klasse oder so gesehen).
Ansonsten ist es wahrscheinlich Overkill dafür jeder Klasse eine Referenz auf sich selbt zurückgeben zu lassen, nur damit man das ev. mal machen kann. (Rückgabewerte kann man da ja auch nicht mehr so schön einbringen)
Bei volkards Beispiel würde ich die erste Variante bevorzugen.
In wirklichem Code würde wahrscheinlich die letzte Variante sehr merkwürdig aussehen..
-
Leute ich kapier des mit den bits no net so ganz. Will jetzt zum bispiel flags setzen. Mach ich mir dann einfach eine char variable die ja 8 bit hat. So und dann muss ich gucken den buchstabe den ich der variable gebe welchem zahlenwert der entspricht und damm schaun wie davon die binäre zahl aussieht? Wenn ich dann genau das 4. Bit ändern will muss ich dass ja mit und oder oder so machen. Und wie kann ich dann z.b abfragen ob genau das 4. Bit true ist?
Danke schonmal;-)
-
Warum nicht einfach std::bitset verwenden?
// Bits: std::bitset<32> myBits; // Bits vertauschen: std::swap(myBits[3], myBits[5]); // Abfragen: if (myBits.test(4)) ...Warum immer kompliziert?
