Bits genau setzen ?



  • troll-fan schrieb:

    @Pelle:
    vielleicht könntest du deinen ursprünglichen gedanken wieder aufgreifen, statt einzelner bits ein array aus 128 chars zu verwenden. ich weiss ja nicht, wie viel speicher deine umgebung hat, aber 'nem ausgewachsenen PC z.b. würden diese 128 bytes nicht wirklich fehlen und obendrein ist diese variante die schnellste. ausserdem hätten die trolle dann keinen stoff mehr für ihren fight, welcher code denn nun am frickligsten sei.

    char array[128];
    #define PLATZ_RESERVIEREN(p) (array[p]=1)
    #define PLATZ_FREIGEBEN(p) (array[p]=0)
    #define IST_PLATZ_RESERVIERT(p) (array[p]==1)
    

    🙂

    bist du ein makro troll ?



  • kenner der trolle schrieb:

    bist du ein makro troll ?

    ja! und?
    🙂



  • Tim schrieb:

    Du findest >>3 so lesbar wie /8? Und &3 so lesbar wie %4?

    wollte ja nur sagen um das "/8" und "%8" kommt man nich rum, ich würde, sofern man keinen nachteil bis auf die bessere lesbarkeit in kauf nehmen muss (und normalerweise muss man das wirklich nicht, denn moderne compiler machen da keinen unterschied mehr) die normalen rechenoperatoren verwenden, also nein.

    Tim schrieb:

    Du findest a und p sind gute Bezeichner?

    naja, die sind vielleicht etwas unglücklich gewählt worden, aber sowas kann man bei einer funktion auch schreiben 😉

    Tim schrieb:

    Und die wichtigste Frage: Was denkst du ist für Anfänger besser geeignet?

    Ohja, da muss ich dir recht geben, nur wer mit bits hantieren will, kommt am binären zahlensystem nicht vorbei - dazu gehören auch, die operatoren.



  • warum nennst du dich scheise
    ?



  • unsigned int iLagerplaetze[4]; // 128 Bits
    int temp;
    

    Verständnisfrage:

    Habe ich das richtig verstanden?

    Aus einem Buch:

    unsigned zahl = 5, ergebnis;
    ergebnis = zahl << 3; // 40 = 5 * 23
    ergebnis = zahl >> 1; // 2 = 5 /21
    

    23 und 21 etc.. wie kommt man auf die werte ??? ok der autor hat auch das int vergessen, denke 23/21 sind auch einfach Schreibfähler...

    Was nervt ist, dass in der Literatur immer davon gesprochen wird, das bestimmte Bits gelöscht werden durch eine so genannte Bitmaske z.B. 0x7F doch ich habe 128 Möglichkeiten, da kann ich doch net alle Bitmasken vorfestlegen??? zudem muss das ganze shit auch ohne bitmasken gehen, dass es nicht in unserem unterricht behandelt wurde. Jetzt habe ich 3 Bücher gekauft und alle haben eine scheiss kurze Einführung und dämliche Beispiele mit der hexadezimalen schreibweise bzw. den bitmasken, muss doch auch ohne gehen???

    Frage:

    zitat wikipedia:"ergebnis = 5 % 2; // ergebnis hat den Wert 1"

    sprich 5/2 = 2 rest 1 also bleibt eins übrig? wenn ja warum ergibt 7 % 2 die Zahl 1 weil 2 genau 3 mal in 7 geht uns 1 übrig bleibt?

    was würde dann 2 % 7 ergeben? 0 ?



  • Hi Leude,

    kämpfe seit ner Stunde mit meinem Linker herum, bin deswegen wohl nimmer aktuell, aber vielleicht macht's die Kürze aus:

    char lkw[16];
    
    // -------------------
    void belege(char platz)
    {
    	unsigned int row, column;
    	platz--;					// Input nicht von 0 bis 127, sondern von 1 bis 128
    	row = platz >> 3;			// entspricht Div 8 -> Byteplatz
    	column = platz % 8;			// modulo 8 -> Bitplatz
    	lkw[row] |= (1 << column);	// Hineingeodert
    }
    

    Einfach mal mit nem Debugger anschauen, vielleicht rieseln dann die Groschen - ich konnte es jetzt nicht, sollte aber stimmen.



  • C/C++ Code:
    unsigned zahl = 5, ergebnis;
    ergebnis = zahl << 3; // 40 = 5 * 23
    ergebnis = zahl >> 1; // 2 = 5 /21

    23 und 21 etc.. wie kommt man auf die werte ??? ok der autor hat auch das int vergessen, denke 23/21 sind auch einfach Schreibfähler...

    Mit 23 und 21 ist wohl 2^3 (2 hoch 3) und 2^1 (2 hoch 1) gemeint.

    Und 2%7 gibt 2, 2%8 und 2%5 und 2%10 übrigens auch.



  • keyword: modulo operator bit shift operator

    operand1 % operand2 immer = 0 wenn beide werte gleich sind;

    operand1 % operand2 immer wert von operand1 wenn operand2 > operand1;

    operand1 % operand2 ist eine division op1 / op2, dabei wird geprüft wie oft op2 in

    op1 passt z.B. 55 % 6 , hier geht die 6 genau 9 mal rein denn 6 * 9 = 54. 10 mal würde die 6 nicht in 55 gehen denn 10 * 6 ergibt 60, demnach bleibt ein Restwert von 1 denn 55 - 54 = 1

    Juchuuu den modulo hab ich jetzt kapiert durch probieren, als 3 C Bücher liegen hier rum und bei allen gabs nix zu verstehn tststs... ich sollte Autor für C Anfänger werden 😃

    void platz_reservieren( int Nr, unsigned int* p )
    
    {   p[(Nr-1)/32] |= (1<<( (Nr-1)%32 ));   }
    

    selbst die Zeile habe ich jetzt endlich verstanden.

    Wenn man sich obige Zeile anschaut muss man sich der Vorrangigkeit der Operatoren bewußt sein, sonst kann alles rauskommen nur net das was richtig ist:

    1. ()
    2. %
    3. -
    4. <<
    

    Damit wird erstmal festgelegt, in welcher Reihenfolge obige Frickelei abgearbeitet wird.

    Beispiel: Lagerplatz zu reservieren wäre 128:

    1. Zuerst (128-1) = 127 // "-" kommt zwar nach % doch "-" ist in der Klammer...
    2. 127 % 32 = 3 mal gehts rein Rest = 31
    3. Dieser Rest 31 bedeutet, dass dass 1 Bit der variablen "Nr" 31 mal nach links geshiftet wird: 1 << 31 wäre das. Rechts von dem 32. bit dann wird alles mit 0 aufgefüllt so: 10000000 00000000 00000000 00000000 <--- Variable "Nr" nach der kompletten rechtsseitigen Berechnung: Nun muss nur noch linksseitige Berechnung vorgenommen werden und da habe ich noch ein kleines Problem:

    p[(Nr-1)/32]
    

    gleiches Beispiel: (128-1)= 127, 127/32 = 3,96

    Wie kann ich einen index von 3,96 in dem Array p[3,96] ansprechen? Ich nehme an es liegt daran, dass die Nachkommastelle(n) bei einer int division einfach abgeschnitten werden. Würde man die Nr-1 nicht machen hätte ich 128/32 wodurch ich den index 4 ansprechen würde was nicht reserviert wurde sprich index out of bounds exception 😃 das ganze mit "|" verknüpft und das Bit 1 wird in p[3] gesetzt! Goil wa ich habs 😮 😮 😃 Danke an frickler mittlerweile mag ich deine Methode weil sie doch sehr ausgeklügelt ist, für einen n00b zwar hartes brot doch irgendwann fällt bei jedem der Groschen :p 👍 👍



  • so wie x +=1 schreiben kann für x = x +1 wie mache ich dies für untenstehenden code?

    p[(Nr-1)/32] |= (1<<( (Nr-1)%32 ));
    

    Das kann ja nicht stimmen oder?

    p[(Nr-1)/32] = p[(Nr-1)/32] | (1<<( (Nr-1)%32 ));
    


  • Pelle schrieb:

    1. Zuerst (128-1) = 127 // "-" kommt zwar nach % doch "-" ist in der Klammer...
    2. 127 % 32 = 3 mal gehts rein Rest = 31
    3. Dieser Rest 31 bedeutet, dass dass 1 Bit der variablen "Nr" 31 mal nach links geshiftet wird: 1 << 31 wäre das. Rechts von dem 32. bit dann wird alles mit 0 aufgefüllt so: 10000000 00000000 00000000 00000000 <---

    Bis hierhin sieht's richtig aus.

    Variable "Nr" nach der kompletten rechtsseitigen Berechnung: Nun muss nur noch linksseitige Berechnung vorgenommen werden und da habe ich noch ein kleines Problem:

    p[(Nr-1)/32]
    

    gleiches Beispiel: (128-1)= 127, 127/32 = 3,96

    Wie kann ich einen index von 3,96 in dem Array p[3,96] ansprechen? Ich nehme an es liegt daran, dass die Nachkommastelle(n) bei einer int division einfach abgeschnitten werden.

    Richtig erkannt - wir reden hier von Ganzzahldivision und dabei werden nachkommastellen einfach weggelassen (127/32==3).

    Das "Nr-1" ist übrigens nötig, weil da jemand den Index von 1 an gezählt hat - ein erfahrener C-Programmierer hätte die Lagerplätze von 0 bis 127 nummeriert.

    Pelle schrieb:

    so wie x +=1 schreiben kann für x = x +1 wie mache ich dies für untenstehenden code?

    p[(Nr-1)/32] |= (1<<( (Nr-1)%32 ));
    

    Das kann ja nicht stimmen oder?

    p[(Nr-1)/32] = p[(Nr-1)/32] | (1<<( (Nr-1)%32 ));
    

    Klar stimmt das so, warum auch nicht?



  • Das kann ja nicht stimmen oder?

    p[(Nr-1)/32] = p[(Nr-1)/32] | (1<<( (Nr-1)%32 ));
    

    Klar stimmt das so, warum auch nicht? [/quote]

    p[(Nr-1)/BITS] &= ~(1<<((Nr-1)%BITS));
    

    das wäre dann auch richtig?

    p[(Nr-1)/BITS] = p[(Nr-1)/BITS] & ~(1<<((Nr-1)%BITS));
    


  • Wenn ich jetzt keinen Tippfehler übersehen habe, ja.



  • Pelle schrieb:

    unsigned int iLagerplaetze[4]; // 128 Bits
    int temp;
    

    Na, mit Sicherheit NICHT 128 Bit ... eher hatte da jemand 128 Bit intus 😃
    Was machst Du Dir Gedanken um den Platz von 128 Bit oder Byte und willst an Bits frickeln, wenn Du dann auf diese Weise Speicher vergeudest.😕
    Mit den Mehrfachdivisionen

    p[(Nr-1)/32] = p[(Nr-1)/32] | (1<<( (Nr-1)%32 ));
    

    verläßt man sich auf die Optimierung des Compilers, aber es gibt wirklich welche, die (Nr-1)/32 mehrfach ausrechnen.:p

    Performance dahin, kaum Platz gespart ... *keine gute Idee*, nur um nicht Schwachsinn 😮 sagen zu müssen



  • pointercrash() schrieb:

    Performance dahin, kaum Platz gespart ... *keine gute Idee*, nur um nicht Schwachsinn 😮 sagen zu müssen

    eben drum, ich hatte weiter oben ein paar schicke macros gepostet (zwar mit flüchtigkeitsfehlern drin), aber davon will ja keiner was wissen.
    🙂



  • macro-troll schrieb:

    eben drum, ich hatte weiter oben ein paar schicke macros gepostet (zwar mit flüchtigkeitsfehlern drin), aber davon will ja keiner was wissen.
    🙂

    doch, ich ! 🙂

    und zwar wieso &3 den selben wert wie %4 liefert.
    kann man das irgendwie mathematisch zeigen ?
    also im moment komme ich nicht drauf wie. 😕



  • macro-troll-fan schrieb:

    kann man das irgendwie mathematisch zeigen ?

    ich kanns zwar nicht mathematisch zeigen, aber im binärsystem funzt dieses speed-modulo auch nur mit zweierpotenzen. alle stellen rechts vom teiler müssen 0 sein, dann isses ohne rest teilbar. in anderen zahlensystemen ist es ja so ähnlich, also im zehnersystem bei allen teilern, die selber glatt durch die basis teilbar sind usw...
    🙂



  • macro-troll-fan schrieb:

    macro-troll schrieb:

    eben drum, ich hatte weiter oben ein paar schicke macros gepostet (zwar mit flüchtigkeitsfehlern drin), aber davon will ja keiner was wissen.
    🙂

    doch, ich ! 🙂
    und zwar wieso &3 den selben wert wie %4 liefert.
    kann man das irgendwie mathematisch zeigen ? ...

    ÖÄhmm, im Prinzip schon, aber es will ja keiner was davon wissen, so why ...



  • pointercrash() schrieb:

    macro-troll-fan schrieb:

    macro-troll schrieb:

    eben drum, ich hatte weiter oben ein paar schicke macros gepostet (zwar mit flüchtigkeitsfehlern drin), aber davon will ja keiner was wissen.
    🙂

    doch, ich ! 🙂
    und zwar wieso &3 den selben wert wie %4 liefert.
    kann man das irgendwie mathematisch zeigen ? ...

    ÖÄhmm, im Prinzip schon, aber es will ja keiner was davon wissen, so why ...

    wenn es niemand wissen wollte, dann würde auch niemand danach fragen.



  • der wissbegierige schrieb:

    wenn es niemand wissen wollte, dann würde auch niemand danach fragen.

    Dachte, Du willst mich veralbern 🤡
    mit %4 führst Du eine Modulo- Division durch. Bei /4 würdest Du im Binärsystem zweimal rechts shiften, also /2 /2. Was da überbleibt, ist das Ergebnis der Integer- Division, was Du nach rechts rausgeshiftet hast, ist der Modulo- Rest. Das sind die unteren beiden Bits und die kannst Du genausogut (naja, zumeist schneller) durch Verundung gewinnen. Daß bei 3 die unteren beiden Bits gesetzt sind, muß ich nicht gesondert erklären, oder? 😉
    Genügt die anschauliche Erklärung, oder soll ich den Bronstein zücken und von dort aus dem Abschnitt Zahlensysteme rezitieren?



  • pointercrash() schrieb:

    Daß bei 3 die unteren beiden Bits gesetzt sind, muß ich nicht gesondert erklären, oder? 😉

    nööööööööö

    pointercrash() schrieb:

    Genügt die anschauliche Erklärung, oder soll ich den Bronstein zücken und von dort aus dem Abschnitt Zahlensysteme rezitieren?

    Nö, nicht nötig, die Erklärung ist spitze 👍
    Danke dafür.

    Also ich es mir aufgeschrieben und mit diversen Zahlen probiert habe, hab ich es auch geblickt *stolz*

    Also, wenn ich %4 haben will, schreibe ich &3.
    Möchte ich %8, schreibe ich &7.
    Will ich %16 kann ich dafür &15 setzen.
    %32 -> &31 usw.

    Also ist immer %(2^x) gleichwertig mit &(2^x-1)

    Jetzt hab auch ich es kapiert 🙂


Anmelden zum Antworten