Bits genau setzen ?
-
naja, arrays fangen bei index 0 an und bits auch. deshalb ist's immer einer weniger als du erwartest.
Das is richtig
Ah okay,
array[byte_position] = array[byte_position] + bit;
geht also auch. bit is in meinem beispiel 16 und die Position 3, also
array[3] = array[3] + 16;
heisst für mich aber jetzt soviel wie
array[3] += 16;Und da wird doch dann nur der gesamte Wert verändert und doch nicht nur ein einzelnes Bit!?
-
16 ist binär 10000. Hab bei 1 Anfangen zu Zählen, wollte das 4. verändern, verändere mit der Angabe 4 das 5. Bit, alles klar - Habs kapiert, Dankeschön!
Aber wenn jetzt das 5. Bit schon auf 1 gesetzt ist und ich es nochmal setze (mit dem + ), wird das 5. doch Null und das 6. gesetzt, das würde ja bei der Version mit | nicht passieren, oder?
-
define Byte usigned char;
Byte wert = 0;
Aufruf:BitSet(&wert,0);
void BitSet(Byte *val,Byte bit) { Byte test_val = 0x01; // test_val sieht so aus 0000 0001 test_val = (test_val << bit); // aus 0000 0001 wird 0000 0010 ? 1x nach links? *val = (*val | test_val); // obiges Änderung 0000 0010 wird bitmäßig auf *val kopiert bzw. gesetzt }
wenn die Funktion wie in meinem buch aufgerufen wird mit
BitSet(&egal,0);
dann wird die Zahl 1 in 0000 0001 gar nicht nach links geschoben richtig? 0 heißt ja 0 mal nach links bzw. 0 stellen öhm was hat die "0" dann für einen Sinn?
Kann mir auch jemand sagen, warum der Autor einen Zeiger für den 1. Parameter der Funktion nimmt?
-
#define PLAETZE 128 #define BITS 8 // Bits pro Byte // Ausgabe des 128 Bit Arrays. // Erste Zeile links: Bit Nr 1, rechts: Bit Nr 8. // Zweite Zeile links: Bit Nr 9, rechts: Bit Nr 16. // . // . // . // Letzte Zeile links: Bit Nr 121, rechts unten: Bit Nr 128 void show128bit( char* p ) { int i,j; for ( i=0; i<PLAETZE/BITS; i++ ) { for ( j=0; j<BITS; j++ ) if ( p[i] & ( 1 << j ) ) printf("1"); else printf("0"); puts(""); } puts(""); } // 1 <= Nr <= 128 void platz_reservieren( int Nr, unsigned char* p ) { if ( Nr < 1 || Nr > PLAETZE ) { printf("Falsche Platznummer: %d", Nr ); return; } p[(Nr-1)/BITS] |= (1<<((Nr-1)%BITS)); } // 1 <= Nr <= 128 void platz_loeschen( int Nr, unsigned char* p ) { if ( Nr < 1 || Nr > PLAETZE ) { printf("Falsche Platznummer: %d", Nr ); return; } p[(Nr-1)/BITS] &= ~(1<<((Nr-1)%BITS)); } int main() { int i=0; unsigned char Lagerplaetze[PLAETZE/BITS]; unsigned char* p = Lagerplaetze; // Alle Plätze Null setzen. memset( p, 0, sizeof(Lagerplaetze) ); // Alle Plätze reservieren; for ( i=1; i<=PLAETZE; i++ ) { platz_reservieren(i,p); } platz_loeschen (128,p); show128bit(p); return 0; }
-
bit-freak schrieb:
nimm doch ein array aus 8 bytes und dann...
#define SetBit(a, p) ((a)[(p)>>3] |= (1<<((p)&3))) #define GetBit (a, p) (!!((a)[(p)>>3] & (1<<((p)&3))))
sollte das nicht jeweils (1<<((p)&7)) heißen wenn du mod 8 berechnen willst...
Tim schrieb:
Ich hab den Müll verstanden und finde es trotzdem nicht toll. Das ist einfach nur Frickelei (auf welchem Niveau auch immer).
quatsch mach ich auch immer so. um das "/8" und "%8" kommt man in dem fall nicht rum, wenn man also die bit-ops verstanden hat, warum nicht...
-
@YaB hui das sieht nett aus R3SP3KT
doch eins hast du vergessen (vllt. hab ichs auch net erwähnt...) bevor ein bit gesetzt wird muss natürlich geprüft werden ob dieses bereits gesetzt ist, denn wenn ja muss ein anderer Lagerplatz ausgesucht werden im Anhaenger...
Sonst schönes Beispiel, doch bei einigen Frickelein steigt mein Verstand aus...
das ist für mich nicht mehr lesbar...
p[(Nr-1)/BITS] &= ~(1<<((Nr-1)%BITS));
Ich bitte um Berücksichtigung meiner Fragen siehe oben ...danke
-
scheise schrieb:
bit-freak schrieb:
nimm doch ein array aus 8 bytes und dann...
#define SetBit(a, p) ((a)[(p)>>3] |= (1<<((p)&3))) #define GetBit (a, p) (!!((a)[(p)>>3] & (1<<((p)&3))))
sollte das nicht jeweils (1<<((p)&7)) heißen wenn du mod 8 berechnen willst...
Tim schrieb:
Ich hab den Müll verstanden und finde es trotzdem nicht toll. Das ist einfach nur Frickelei (auf welchem Niveau auch immer).
quatsch mach ich auch immer so. um das "/8" und "%8" kommt man in dem fall nicht rum, wenn man also die bit-ops verstanden hat, warum nicht...
Du findest >>3 so lesbar wie /8? Und &3 so lesbar wie %4? Du findest a und p sind gute Bezeichner? Du findest !! lesbarer als ein (bool)(expression)? Du findest Makros besser als Funktionen? Und die wichtigste Frage: Was denkst du ist für Anfänger besser geeignet?
-
Du findest >>3 so lesbar wie /8? Und &3 so lesbar wie %4? Du findest a und p sind gute Bezeichner? Du findest !! lesbarer als ein (bool)(expression)? Du findest Makros besser als Funktionen? Und die wichtigste Frage: Was denkst du ist für Anfänger besser geeignet?
Jetzt komm endlich ich zum Zug...(huch schon wieder...) Egal was Tim beides ist für Anfänger völlig ungeeignet. Ich weiß zwar dass meine Fragen generell hier nie beachtet werden warum auch immer doch ich stell einfach mal eine weitere...
nehmen wir an wir hätten:
unsigned int iLagerplaetze[4];
Für alle Schlaumeier hier ganz bewußt: --> Die Routine läuft NUR und EXPLIZIT in der WINDOWS32 Konsolenkeksedose das heißt ein int hat hier IMMER 32 BiT!!!
so...nehmen wir weiter an iLagerplaetze hat diese Belegung:
00000000001000000000000000000000 = 32Bit
00000000000000000100000000000000 = 32Bit
00000100000000000100000001000000 = 32Bit
00000000000010000000010000000000 = 32Bitund nun möchte ich Lagerplatz 128 reservieren sprich Bit 127...
wie mache ich das mit folgender Funktion?
Kann mir das jemand zeigen? und da soll man nicht pampig werden *pfeiff*...
void BitSet(Byte *val,Byte bit) { Byte test_val = 0x01; test_val = (test_val << bit); *val = (*val | test_val); }
-
Pelle schrieb:
dann wird die Zahl 1 in 0000 0001 gar nicht nach links geschoben richtig?
richtig
Pelle schrieb:
0 heißt ja 0 mal nach links bzw. 0 stellen öhm was hat die "0" dann für einen Sinn?
die funktion hätte gern einen parameter, möchte man das erste bit
setzen, ist die funktion mit der 0 aufzurfen.Pelle schrieb:
Kann mir auch jemand sagen, warum der Autor einen Zeiger für den 1. Parameter der Funktion nimmt?
ja.
der wert, der übergeben wird, soll ja verändert werden.
ohne zeiger würde der wert nur in den parameter kopiert, aber nicht
verändert werden.Pelle schrieb:
das ist für mich nicht mehr lesbar...
p[(Nr-1)/BITS] &= ~(1<<((Nr-1)%BITS));es geht ja darum das 128 bit array zu adressieren.
hier ein beispiel mit 40 bit, von links nach rechts gelesen
11111111|11111111|11111111|11111111|11111111mit p[0], p[1] usw springst du immer 8 bit, also ein byte weiter.
p[0] adressiert die ersten 8 bit, p[1] die zweiten 8 usw.(Nr-1)/BITS ist eine integerdivision, der nachkommateil wird
abgeschnitten, d.h. 1/BITS = 0, 2/BITS =0 ... 8/8 = 1, 9/8 = 1 usw.Nr kann werte von 1 bis 128 annehmen, demzufolge kann
Nr-1 werte von 0 bis 127 annehmen
damit kann (Nr-1)/BITS werte von 0 bis 15 annehmen.
mit p[(Nr-1)/BITS]
können wir also die byte-grenzen p[0] ... p [15] adressieren.um jetzt an die einzelnen bits ranzukommen, erstellt man sich eine
bitmaske, die man mit dem array vernüpft.als rechenbeispiel möchte ich mal PlatzNr 9 löschen, also Nr = 9.
(Nr-1)/BITS liefert mir: (9-1)/8 = 1, bekomme also p[1].
das ist die linke seite des ausdrucks
p[(Nr-1)/BITS] &= ~(1<<((Nr-1)%BITS)) <=> p[1] &= ~(1<<((Nr-1)%BITS))um an das bit ranzukommen erstelle ich die bitmaske:
~(1<<((Nr-1)%BITS)) wobei % der modulo-operator ist((Nr-1)%BITS) ergibt: (9-1)%8 = 8%8 = 0
erhalte also als zwischenergebnis auf der rechten seite im ausruck:
~(1<<(0)) <=> ~1vom dem gesamten ausdruck bleibt also übrig:
p[1] &= ~1binär sieht das so aus:
die eins wird negiert und ich erhalte, von links nach rechts gelesen:
01111111schreibe ich p[1] binär, das ist der zweite byte-block,
erhalte ich: 1111111111111111 & 01111111 ergibt 0111111, das ist der wert der in p[1] gespeichert
wird.aus dem obigen 40 bit array wird also
11111111|01111111|11111111|11111111|11111111
damit hätte ich platz nr 9 gelöscht.
-
Pelle schrieb:
so...nehmen wir weiter an iLagerplaetze hat diese Belegung:
00000000001000000000000000000000 = 32Bit
00000000000000000100000000000000 = 32Bit
00000100000000000100000001000000 = 32Bit
00000000000010000000010000000000 = 32Bitund nun möchte ich Lagerplatz 128 reservieren sprich Bit 127...
wie mache ich das mit folgender Funktion?
Kann mir das jemand zeigen? und da soll man nicht pampig werden *pfeiff*...mit deiner BitSet funktion kannst 32 bits adressieren, wenn du den datentypen änderst:
void BitSet( int *val, int bit ) { int test_val = 0x01; test_val = (test_val << bit); *val = (*val | test_val); }
wobei auch verkürzt schreiben kannst:
void BitSet( int *val, int bit ) { *val |= (0x01 << bit); }
um einen 128 bit bereich adressieren zu können, musst du ja irgendwie durch ein array
wandern können. dafür kannst du eine von den genannten möglichkeiten wählen.
dieses mal werden die bits von rechts nach links gelesen:int ist_platz_reserviert( int Nr, unsigned int* p ) { return (p[(Nr-1)/32] & (1<<( (Nr-1)%32 )) ); } void platz_reservieren( int Nr, unsigned int* p ) { p[(Nr-1)/32] |= (1<<( (Nr-1)%32 )); } void showbin( unsigned int* p ) { int i, j; for ( i=0; i<4; i++ ) { for ( j=31; j>=0; j-- ) { if ( p[i] & ( 1 << j ) ) printf("1"); else printf("0"); } puts(""); } puts(""); } int main() { //31 23 15 7 Array-Index Hex //00000000|00100000|00000000|00000000 0 0x200000 //00000000|00000000|01000000|00000000 1 0x4000 //00000100|00000000|01000000|01000000 2 0x4004040 //00000000|00001000|00000100|00000000 3 0x80000 unsigned int iL[4] = { 0x200000, 0x4000, 0x4004040, 0x80000 }; int Nr = 128; if ( ist_platz_reserviert( Nr, iL ) ) printf("Platz Nr. %d ist reserviert:\n", Nr ); else printf("Platz Nr. %d ist nicht reserviert.\n", Nr ); showbin(iL); platz_reservieren( Nr, iL ); if ( ist_platz_reserviert( Nr, iL ) ) printf("Platz Nr. %d ist reserviert:\n", Nr ); else printf("Platz Nr. %d ist nicht reserviert.\n", Nr ); showbin(iL); return 0; }
-
@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)
-
(Nr-1)/BITS ist eine integerdivision, der nachkommateil wird
abgeschnitten, d.h. 1/BITS = 0, 2/BITS =0 ... 8/8 = 1, 9/8 = 1 usw.1/8 = 0,2 ? 2/8 = 0...8 ?? die komplette Zeile kann ich nicht nachvollziehen, kannst du das nochmals erläutern?
Wenn Nr der zu reservierende Platz ist Minus die 1 da 127stes bit Platz 128 ist... angenommen platzNr = 17 --> 17-1 /8 (Bits) = 16 /8 = 2 das würde beudeten p[2] also würde das 3 bit z.b. gesetzt, doch die platzNr war 17 sprich das 17. bit müsste gesetzt werden nicht das 3 ?
@troll-fan dannke, aber das hatte mit bitmasken ja nichts mehr zu tun daher komme ich von der idee weg, geht ja auch um dern lerneffekt etc...
-
1/8 = 0 KOMMA 2/8 = 0 KOMMA ... usw
-
Pelle1 schrieb:
das würde beudeten p[2] also würde das 3 bit z.b. gesetzt, doch die platzNr war 17 sprich das 17. bit müsste gesetzt werden nicht das 3 ?
nö, mit p[0], p[1], p[2] adressierst du jeweils 8 bit, wenn es char arrays sind:
11111111 p[0]
11111111 p[1]
11111111 p[2]
.
.
.
uswdie bitmaske legt dann fest, welches bit von den 8 aus/eingeschaltet wird
-
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.