Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Nur 5 Bit kopieren (https://www.delphipraxis.net/35339-nur-5-bit-kopieren.html)

andy65 5. Dez 2004 18:54


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

Ultimator 5. Dez 2004 18:55

Re: Nur 5 Bit kopieren
 
Man kann auf Bits nicht direkt zugreifen, soweit ich weiß, allerhöchstens auf Bytes. :-?

Jens Schumann 5. Dez 2004 19:13

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

Assarbad 5. Dez 2004 20:40

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:
a := (a and (not $7C)) or (b and $7C);
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!

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:
Teil1 = a and (not $7C) = 0101010101010101 and 1111111110000011
Ü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):
Code:
  0101010101010101
& 1111111110000011
= 0101010100000001
Code:
Teil2 = b and $7C = 1110001110001110 and 0000000001111100
Das gleiche für b and $7C:
Code:
  1110001110001110
& 0000000001111100
= 0000000000001100
Code:
a = Teil1 or Teil2
... danach werden beide "Zwischenergebnisse" per logischem ODER verknüpft:
Code:
  0101010100000001
| 0000000000001100
= 0101010100001100
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:

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 Delphi-Referenz durchsuchenTBits 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.

Leuselator 5. Dez 2004 20:46

Re: Nur 5 Bit kopieren
 
das vorangegangene Beispiel löscht die anderen Bits (welche Du vielleicht noch brauchst...
Delphi-Quellcode:
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
Gruß
[edit]Zu langsam und lang nicht so schön wie Assarbad :-) [/Edit]

andy65 5. Dez 2004 22:04

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:
 
  a := Quelle and (not Mask);
  b := Ziel and Mask;
  Resultat := a or b;
@Leuselator
Leider erzeugt Dein Code in der Zeile

Delphi-Quellcode:
Mask := (power(2, Bits + Shift) -1) xor (power(2, Shift) -1);
folgender Fehler

Operator ist auf diesen Operandentyp nicht anwendbar

Gruss
Andy

Assarbad 5. Dez 2004 22:23

Re: Nur 5 Bit kopieren
 
Zitat:

Zitat von andy65
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:
 
  a := Quelle and (not Mask);
  b := Ziel and Mask;
  Resultat := a or b;

Korrekt (für die ersten beiden, das dritte hab ich nicht im Kopf gelöst :-D). Allerdings ist es egal, ob die Bits zusammenhängen. Der Witz ist, daß die Maske ("Mask" bei dir) eine 1 an der Bitposition zu kopierender Bits haben muß und überall sonst eine 0. Weil eben beim logischen UND nur jene Bits erhalten bleiben, bei denen auf der jeweils gleichen Position beide mit 1 besetzt sind.

Leuselator 6. Dez 2004 01:09

Re: Nur 5 Bit kopieren
 
Delphi-Quellcode:
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)));
macht auch nur Sinn, wenn Deine Bits "zusammenhängend", also ohne Bit-Lücken sind.
Gruß

Assarbad 6. Dez 2004 08:40

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:
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
Damit kann man von rechts beginnend eine beliebige Binärzahl nach Hex umwandeln:

Code:
    <---<---<---<---<---<---<---<---<---<---<---<---
   1010101010101001011100101101010101010010110101101
^   ^   ^   ^   ^   ^   ^   ^   ^   ^   ^   ^   ^
1   5   5   5   2   E  5   A  A  A  5   A  D
Fehlende Stellen zu einem vollen "Vierer" werden links angefügt (oder hinzugedacht).

andy65 6. Dez 2004 11:52

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:
b := Ziel and Mask
setze ich für Ziel 0 ein und für Mask? $0?

Gruss und Danke
Andy


Alle Zeitangaben in WEZ +1. Es ist jetzt 05:20 Uhr.
Seite 1 von 2  1 2      

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