Nur 5 Bit kopieren
Hallo
Ich hoffe ich bin hier im richtigen Subforum. Ich habe das Problem das ich nur 5 Bit einer Word-Variavle in einen neue Variable kopieren mus. Wie kann ich dies erreichen? Ist es möglich eine Variable zu definieren welche nur 5 Bit gross ist? Gruss Andy |
Re: Nur 5 Bit kopieren
Man kann auf Bits nicht direkt zugreifen, soweit ich weiß, allerhöchstens auf Bytes. :-?
|
Re: Nur 5 Bit kopieren
Hallo,
wenn du die 5 niederwertigen Bits aus a in b kopieren möchtest dann schreibe doch
Code:
b:=a and $0000001F
|
Re: Nur 5 Bit kopieren
Tach Post,
nimm dir mal den CALC.EXE (Windows-Rechner) von MS "zur Hand". Jetzt überlegst du, welche Bits du kopieren willst. Sagen wir mal Bit 2 bis 6 (Achtung, die Zälung beginnt bei 0 als niederwertigstem Bit). In Calc würdest du also in Binärmodus (und Word!!!) schalten und 1111100 eingeben (eben Bit 2 - 6 auf 1 gesetzt). Danach wandelst du es in eine Hexadezimalzahl: $7C in unserem Fall. Willst du nun die entsprechenden Bits kopieren, ohne daß Verluste der anderen Bits im Zieloperanden wichtig sind, dann machst du es wie oben beschrieben. Willst du aber nur diese 5 Bits kopieren und alle anderen erhalten, mußt du einen anderen Weg beschreiten. Grundlage bleibt jedoch der Code von Jens. Nehmen wir an, a und b sind vom Typ Word. Desweiteren wollen wir wie oben geschrieben die Bits 2-6 kopieren aus b nach a, jedoch sollen die nicht betroffenen restlichen 11 Bits in a unangetastet bleiben. Unangetastet ist zuviel gesagt, da dies nicht geht. ABER wir können die Informationen dieser Bits erhalten:
Delphi-Quellcode:
Wie man sehen kann, ist der zweite Teil ("b and $7C") entsprechend Jens' Ausführungen. Dabei "maskieren" wir b so aus, daß alle Bits außer den 5 zu kopierenden Null werden!
a := (a and (not $7C)) or (b and $7C);
Der erste Teil macht etwas ähnliches. Da wir aber "not $7C" haben, werden in a die 5 entsprechenden zu den zu kopierenden Bits auf Null gesetzt. Danach wird mit einem logischen "oder" eine Verknüpfung der beiden "Masken" vorgenommen. Machen wir es anschaulich mit einzelnen Bits (Binärdarstellung).
Code:
a = 0101010101010101
b = 1110001110001110 $7C = 0000000001111100 <- konstant not $7C = 1111111110000011 <- konstant
Code:
Übereinander geschrieben ((1 and 1) = 1; (1 and 0) = (0 and 1) = (0 and 0) = 0 - also wird das Ergebnis nur dann 1, wenn beide Werte an der Bitposition eine 1 haben):
Teil1 = a and (not $7C) = 0101010101010101 and 1111111110000011
Code:
0101010101010101
& 1111111110000011 = 0101010100000001
Code:
Das gleiche für b and $7C:
Teil2 = b and $7C = 1110001110001110 and 0000000001111100
Code:
1110001110001110
& 0000000001111100 = 0000000000001100
Code:
... danach werden beide "Zwischenergebnisse" per logischem ODER verknüpft:
a = Teil1 or Teil2
Code:
Wie man sieht, bleiben die Bits aus dem ursprünglichen a so erhalten und die 5 zu kopierenden von b überschreiben die alten 5 entsprechenden Bits aus a:
0101010100000001
| 0000000000001100 = 0101010100001100 Farbkodiert (rot = alt aus a; grün = neu aus b): 0101010100001100 Das Prinzip bleibt das gleiche, egal ob man mit Byte, Word oder DWORD (oder noch größer) arbeitet. Übrigens ist Byte tatsächlich die kleinste zusammenhängende Einheit, die modifiziert werden kann. Der Rest (Bits) muß auf Umwegen geschehen. Die Klasse TBits könnte dir übrigens evtl. helfen Übrigens erlaubt VC die Deklaration von sog. "Bit fields", welche allerdings auch mindestens die Größe des jeweils größeren integralen Typs (i.e. Byte, Word, DWORD) haben. Sie erlauben halt die einfachere Manipulation einzelner Bits, sowie Type-Castings. |
Re: Nur 5 Bit kopieren
das vorangegangene Beispiel löscht die anderen Bits (welche Du vielleicht noch brauchst...
Delphi-Quellcode:
Gruß
var a,
b, c word; Bits : Integer; Shift :Integer; Maske : Word; begin Bits := 5; Shift := 4; // du willst also bit 4,5,6,7 und 8 übertragen Mask := (Word(trunc(power(2,Bits+Shift)-1))) xor (Word(trunc(power(2,Shift)-1))); a := IrgendeinWert; b := EinAndererWert; b := b or Mask; // in b sind nun alle 5 Bits gesetzt b := b xor Mask; // nun sind sie alle gelöscht c := a and Mask; // c enthält nur die gesuchten Bits aus a b := b or c; // die 5 Bits sind in b genauso gesetzt wie in a // Kurzversion: b := ((b or Mask) xor Mask) or (a and Mask); // nach Assarbad: b := (b and (not Mask)) or (a and Mask); end [edit]Zu langsam und lang nicht so schön wie Assarbad :-) [/Edit] |
Re: Nur 5 Bit kopieren
Hallo zusammen und besten Dank erstmal für Eure Antworten
Bit-Operationen waren schon in der Schule nie so mein Ding @Assarbad Wenn ich Dich richtig verstanden habe müssten die Masken für die Bits welche kopiert werden müssen wie folgt aussehen Bit 0-4 1Fh Bit 5-9 3E0h Bit 10-14 7C00h Der Code dazu
Delphi-Quellcode:
@Leuselatora := Quelle and (not Mask); b := Ziel and Mask; Resultat := a or b; Leider erzeugt Dein Code in der Zeile
Delphi-Quellcode:
folgender Fehler
Mask := (power(2, Bits + Shift) -1) xor (power(2, Shift) -1);
Operator ist auf diesen Operandentyp nicht anwendbar Gruss Andy |
Re: Nur 5 Bit kopieren
Zitat:
|
Re: Nur 5 Bit kopieren
Delphi-Quellcode:
macht auch nur Sinn, wenn Deine Bits "zusammenhängend", also ohne Bit-Lücken sind.
power liefert datentyp extended zurück - mußt Du also noch casten:
Mask := (Word(trunc(power(2,Bits+Shift)-1))) xor (Word(trunc(power(2,Shift)-1))); Gruß |
Re: Nur 5 Bit kopieren
Hiho nochmal.
Ein Trick noch im Umgang mit Binärzahlen/Hexzahlen. Vielleicht kennen einige schon den Begriff Nibble. Mit "B", nicht mit "P" - ist ein reiner IT-Begriff, also keine schweinischen Gedanken ;) Also ein Nibble sind jeweils 4 Bit. Außerdem wissen wir, daß die kleinste Zahl die ein Byte annehmen kann $00 ist und die größte $FF. Wir sehen also, daß eine Hex-Ziffer pro 4 Bit benutzt wird. Dies ist eine generelle Regel. Wer mal eine riesige Binärzahl nach Hex umwandeln muß, oder umgekehrt, der schreibt sich eine Lookup-Table:
Code:
Damit kann man von rechts beginnend eine beliebige Binärzahl nach Hex umwandeln:
0000 = 0
0001 = 1 0010 = 2 0011 = 3 0100 = 4 0101 = 5 0110 = 6 0111 = 7 1000 = 8 1001 = 9 1010 = A 1011 = B 1100 = C 1101 = D 1110 = E 1111 = F
Code:
Fehlende Stellen zu einem vollen "Vierer" werden links angefügt (oder hinzugedacht).
<---<---<---<---<---<---<---<---<---<---<---<---
1010101010101001011100101101010101010010110101101 ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ 1 5 5 5 2 E 5 A A A 5 A D |
Re: Nur 5 Bit kopieren
Hallo
Ich habe noch eine ergänzungsfrage resp. verständnissfragen Wenn ich zum Beispiel Bit 5 - 9 in eine neue Variable kopieren will mach ich das wie oben beschrieben. Mit dieser Funktion werden die Bits aber wieder an die Stellen 5 - 9 kopiert. Richtig? Ich möchte diese Bits aber in eine leere Variable auf die Bits 0 - 4 kopieren. Wenn ich folgendes verwende
Delphi-Quellcode:
setze ich für Ziel 0 ein und für Mask? $0?
b := Ziel and Mask
Gruss und Danke Andy |
Alle Zeitangaben in WEZ +1. Es ist jetzt 05:20 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz