![]() |
Bitoperationen
Hallo Delphi-PRAXIS,
diesmal sind die "Lehrer" unter euch gefragt. Ich bin sehr unerfahren mit Bitoperationen, möchte es aber unbedingt lernen/benutzen. Für einige von euch ist es bestimmt das einfachste von der Welt, also bitte korrigiert mich und schreit wenn ich völlig falsch liege. Ich habe:
Code:
Das möchte ich in 3 Bits unterteilen, also sodass ich Attribut1 (0,0,0), Attribut2 (0,0,1), Attribut3 (0,1,0) usw. Ich brauche so 7-8 verschiedene Möglichkeiten. Wie lege ich das so an?
Attribut : byte;
Aber jetzt hatte ich irgendwann was gelesene, dass man daraus $00 macht und damit arbeitet... Wie funktioniert das nun wieder? Was bringt es shift left (shl) und shift left (shr) zu benutzen... Geht es hierbei wieder nur um Ressourcensparen? Seid geduldig mit mir ;) FG Dunkelbunt |
AW: Bitoperationen
Hexadezimalzahlen (dein $xx) wie man Dezimal in Hexadezimal umwandelt, kannst du bestimmt überall erfahren.
$00, $01, $02 ... $07 oder eben doch einfach dezimal 0 bis 7 nutzen Statt deinem Byte und bei dieser Bitfolge (falls ich sie richtig erkannt hab) kannst du auch Folgendes nehmen:
Delphi-Quellcode:
.
TMyType = (Attribut1, Attribut2, Attribut3, ... , Attribut8);
PS: Bei 3 Bit und 8 Möglichkeiten kommt man mit Binäroperationen eh nicht so gut voran. Hier ist ein Cast besser ... siehe den ENUM vom Anfang oder eben ganz einfach die Zahlen von 0 bis 7. |
AW: Bitoperationen
Danke erstmal,....
wie lege ich überhaupt fest aus wievielen Bit meine Zahl besteht? Momentmanl... wenn ich Byte nehme ebsteht es ja automatsich aus 8 bit..... denkfehler |
AW: Bitoperationen
es kommt darauf an, wie du deine Werte kodieren möchstest.
Du kannst die Werte z.B. im ![]() Oder binär jeden Wert in einem einzelnem Bit. Oder sonstwie. Wenn du jeden wert in einem Bit kodierst, dann machen sich Bitvergleiche natürlich einfacher und man kann sogar alle Werte zusammen in einer Variable unterbekommen (SET). Es kommt also erstmal darauf an, was genau du vor hast. |
AW: Bitoperationen
Hallo,
perfekt wäre alle Werte in einer Variable zu kodieren. Dann könnte ich mir die 8 Bit aufteilen. |
AW: Bitoperationen
Eine Variable ist in Delphi immer ganze 1, 2, 4 oder 8 Byte groß.
Oder eben eine Mischung daraus (Records/Objekte). Wie gesagt, es gibt mehrere Varianten 8 Werte in einer Variable zu speichern .... es kommt allerdings darauf an was man damit erreichen will ... jenachdem eignet sich die einer oder andere Variante mehr dafür. |
AW: Bitoperationen
Zitat:
Das ergibt letzendlich 2^8 (= 256) Möglichkeiten, was wiederum einem Byte entspricht. So, zu den einzelnen Bitoperationen: OR Per Or kannst du Bits verknüpfen, wobei gilt: mindestens ein Zustand von 2 muss 1 sein, damit letzendlich der Gesamtzustand 1 ist: 0 or 0 = 0 1 or 0 = 1 0 or 1 = 1 1 or 1 = 1 AND Per And verknüpfst du wie folgt: es müssen beide Zustände 1 sein, damit der Gesamtzustand 1 ist: 0 and 0 = 0 1 and 0 = 0 0 and 1 = 0 1 and 1 = 1 XOR Auch exklusives Or: es muss nur einer der beiden Zustände 1 sein: 0 xor 0 = 0 1 xor 0 = 1 0 xor 1 = 1 1 xor 1 = 0 SHL Shift Left: verschiebt die Bits Y nach links um X Bits: Y shl X 10101101 shl 1 = 01011010 01 shl 2 = 100 SHR Shift Right: verschiebt nach rechts: 10 shr 1 = 01 01 shr 1 = 00 Dann gibts noch ROL und ROR. Diese "Rollen" die Werte nach L oder R. Rollen im Sinne von - was hinten ist und normalerweise abgeschnitten wird, kommt an den Anfang: 1100 rol 1 = 1001 1001 rol 1 = 0011 Sofern du das verstanden hast, gehts hier weiter: Sagen wir, du willst von einem Byte die Least Significant Bits beibehalten und die restlichen ignorieren/wegbringen (kurz angemerkt: die 4 Least Significant Bits sind 0000XXXX die mit X gekennzeichnet). Dann gehst du wie folgt vor: 0000XXXX and 00001111 -------- ////XXXX ganz egal, was in X steht, der Wert bleibt erhalten und die restlichen Werte gehen verloren. Auch wenn da statt 0 etwas andere drin stehen würde. Nun musst du nur noch mehr wissen, wie man den dezimalen Wert binär darstellt. Dazu einfach mal googlen oder so. Ein praktisches Beispiel:
Delphi-Quellcode:
Demotype TBitRange = 0..7; TBitState = Boolean; TBitByte = record private FValue: Byte; function GetBits(BitIndex: TBitRange): TBitState; procedure SetBits(BitIndex: TBitRange; const Value: TBitState); procedure SetValue(const Value: Byte); public property Value: Byte read FValue write SetValue; property Bits[BitIndex: TBitRange]: TBitState read GetBits write SetBits; default; function AsString(): String; end; const BitChar : Array[TBitState] of Char = ( '0', '1' ); BitTable : Array[TBitRange] of Byte = ( 1, 2, 4, 8, 16, 32, 64, 128 ); { TBitByte } function TBitByte.AsString: String; var i: TBitRange; begin SetLength( Result, 8 ); for i := 0 to 7 do Result[8-i] := BitChar[Bits[i]]; end; function TBitByte.GetBits(BitIndex: TBitRange): TBitState; begin Result := FValue and BitTable[BitIndex] > 0; end; procedure TBitByte.SetBits(BitIndex: TBitRange; const Value: TBitState); begin FValue := FValue or BitTable[BitIndex]; end; procedure TBitByte.SetValue(const Value: Byte); begin FValue := Value; end;
Delphi-Quellcode:
ergibt "15 - 00001111"
var
i: TBitRange; B: TBitByte; begin for i := 0 to 3 do B[i] := True; Writeln( B.Value, ' - ', B.AsString ); Readln; end. |
AW: Bitoperationen
Danke, super.
Damit kann ich was anfangen :) EDIT: Wegen der Vollständigkeit:
Delphi-Quellcode:
EDIT2:
function IntToBin(Int: Integer): String;
var i : Integer; begin Result := ''; for i := 7 downto 0 do Result := Result + IntToStr((Int shr i) and 1); end; function BinToInt(Binary: String): Integer; var i : Integer; begin Result := 0; for i := Length(Binary) downto 1 do Inc(Result, StrToInt(Binary[i]) * 1 shl (Length(Binary) - i)); end; Bin etwas verwirrt... wollte eigentlich nur Schruftfarben mit Bits kodieren.... FG Dunkelbunt |
AW: Bitoperationen
Wer das Problem mit mir teilt:
![]() ein gutes Tutorial von DeddyH, danke an dieser Stelle. FG Dunkelbunt |
AW: Bitoperationen
Danke für die Blumen :D
|
AW: Bitoperationen
Hallo,
:-D Ich muss mich aber doch nochmal melden. Ich habe mir nun Bits angelegt um die Farben von Text zu steuern, zum testen. Aber es funktioniert noch nicht.... Es sieht bis jetzt so aus:
Delphi-Quellcode:
Ich hoffe das reicht um mein Problem nachzuvollziehen.
type
TBuchstabe = record Zeichen : char; Attribut : byte; end; ... const flschwarz = 1; //Geändert! flblau = 2; flrot = 4; flgruen = 8; flgrau = 16; ... var buchstabe : array of array of TBuchstabe; ... procedure TForm1.schwarzClick(Sender: TObject); begin buchstabe[PositionSpalte,PositionZeile].attribut:= $FF shr 7 shl 7; //1. Bit setzen //Andere Farbbits ausschalten if buchstabe[PositionSpalte,PositionZeile].attribut and flblau > 0 then buchstabe[PositionSpalte,PositionZeile].attribut := buchstabe[PositionSpalte,PositionZeile].attribut and not flblau; end; ... procedure TForm1.blauClick(Sender: TObject); begin buchstabe[PositionSpalte,PositionZeile].attribut:= $FF shr 7 shl 6; //2. Bit setzen //Andere Farbbits ausschalten if buchstabe[PositionSpalte,PositionZeile].attribut and flgruen > 0 then buchstabe[PositionSpalte,PositionZeile].attribut := buchstabe[PositionSpalte,PositionZeile].attribut and not flgruen; if buchstabe[PositionSpalte,PositionZeile].attribut and flrot > 0 then buchstabe[PositionSpalte,PositionZeile].attribut := buchstabe[PositionSpalte,PositionZeile].attribut and not flrot; if buchstabe[PositionSpalte,PositionZeile].attribut and flgrau > 0 then buchstabe[PositionSpalte,PositionZeile].attribut := buchstabe[PositionSpalte,PositionZeile].attribut and not flgrau; end; ... procedure buchstaben; var i,n : integer; begin for i := 1 to AnzahlSpalten do for n := 1 to AnzahlZeilen do begin // Bit Abfragen if (buchstabe[i,n].Attribut and flschwarz > 0) then Form1.Canvas.Font.Color:=clblack; if (buchstabe[i,n].Attribut and flblau > 0) then Form1.Canvas.Font.Color:=clblue; if (buchstabe[i,n].Attribut and flrot > 0) then Form1.Canvas.Font.Color:=clred; if (buchstabe[i,n].Attribut and flgruen > 0) then Form1.Canvas.Font.Color:=clgreen; if (buchstabe[i,n].Attribut and flgrau > 0) then Form1.Canvas.Font.Color:=clgray; Form1.Canvas.TextOut(spalten[i],zeilen[n],buchstabe[i,n].zeichen); end; end; FG Dunkelbunt |
AW: Bitoperationen
Zitat:
|
AW: Bitoperationen
Ähm, ...
Wie kann ich das denn sonst machen ich hatte mir gedacht: $FF = 11111111 1111 1111 shr 7 = 0000 0001 shl 5 = 0010 000 Dann habe ich an der 3. Stelle ein Bit ... FG Dunkelbunt |
AW: Bitoperationen
Delphi-Quellcode:
[edit] Mir fällt gerade auf, dass Dein $16 nicht richtig ist, das muss entweder einfach 16 oder $10 heißen. [/edit]
Attribut := $20; //oder die entsprechende Konstante
|
AW: Bitoperationen
Es funktioniert immernoch nicht :cry:
Delphi-Quellcode:
Was mache ich falsch....
procedure TForm1.blauClick(Sender: TObject);
begin buchstabe[PositionSpalte,PositionZeile].attribut:= $20; //2. Bit setzen end; procedure TForm1.schwarzClick(Sender: TObject); begin buchstabe[PositionSpalte,PositionZeile].attribut:= $1; //1. Bit setzen end; procedure buchstaben; // Vorbereitung für das schnelle anzeigen von Buchstaben var lauf,i,n : integer; begin for i := 1 to AnzahlSpalten do for n := 1 to AnzahlZeilen do begin // Bit Abfragen if (buchstabe[i,n].Attribut and flschwarz > 0) then Form1.Canvas.Font.Color:=clblack; if (buchstabe[i,n].Attribut and flblau > 0) then Form1.Canvas.Font.Color:=clblue; if (buchstabe[i,n].Attribut and flrot > 0) then Form1.Canvas.Font.Color:=clred; if (buchstabe[i,n].Attribut and flgruen > 0) then Form1.Canvas.Font.Color:=clgreen; if (buchstabe[i,n].Attribut and flgrau > 0) then Form1.Canvas.Font.Color:=clgray; Form1.Canvas.TextOut(spalten[i],zeilen[n],buchstabe[i,n].zeichen); end; end; const flschwarz = $1; flblau = $20; flrot = $36; flgruen = 8; flgrau = 16; TBuchstabe = record Zeichen : char; Attribut : byte; end; buchstabe : array of array of TBuchstabe; ... |
AW: Bitoperationen
Zitat:
Per $ gibt man in Delphi anstatt Dezimalwerte Hexwerte ein. Diese haben die Basis 16, anstatt 10. $10 (Hex) = 16 (Dez). $20 (Hex) = 32 (Dez). Und jetzt kommts... DAS - HAT - NICHTS - MIT - BITS - ZU - TUN |
AW: Bitoperationen
Zitat:
|
AW: Bitoperationen
Ich wusste, dass diese Antwort kommt.
Relativ gesehen nicht. Also er hat sich ja dabei gedacht, dass das einzelne Bits präsentiert. Nochmal zum Problem:
Code:
Diese Folge kann man auch als eine 2er Potenz anschreiben:
Bit 1 = 00000001 = 1 (Dezimal) = $01 (Hexadezimal)
Bit 2 = 00000010 = 2 (Dezimal) = $02 (Hexadezimal) Bit 3 = 00000100 = 4 (Dezimal) = $04 (Hexadezimal) Bit 4 = 00001000 = 8 (Dezimal) = $08 (Hexadezimal) Bit 5 = 00010000 = 16 (Dezimal) = $10 (Hexadezimal) Bit 6 = 00100000 = 32 (Dezimal) = $20 (Hexadezimal) Bit 7 = 01000000 = 64 (Dezimal) = $40 (Hexadezimal) Bit 8 = 10000000 = 128 (Dezimal) = $80 (Hexadezimal) 2^0, 2^1, 2^2, 2^3, 2^4, 2^5, 2^6, 2^7, ... Edit: Ach übrigens, warum verwendest du nicht einfach mein kleines Record um die Einzelnen Bits zu setzen?
Delphi-Quellcode:
// Ersetze folgendes
type TBuchstabe = record Zeichen : char; Attribut : byte; end; // mit das hier: type TBuchstabe = record Zeichen : char; Attribut : TBitByte; end; |
AW: Bitoperationen
Gibt es einen bestimmten Grund dafür, dass man nicht einfach TColor nimmt?
|
AW: Bitoperationen
Zitat:
Wieso kommst du jetzt auf TColor? So viele Bits braucht er doch gar nicht .... |
AW: Bitoperationen
Ja und? Er will doch einfach nur Farben verwalten, da kann man die doch auch direkt nehmen. Oder alternativ eine Enumeration, das dürfte zumindest einfacher sein als umständlich mit Bits herumzurechnen.
|
AW: Bitoperationen
Hallo,
die Frage mit TColor ist berechtigt, aber ich brauche wirklich nicht soviele bits UND es komen später noch viele andere schöne eigenschaften hinzu. Das kannst du aber logischerweise nicht wissen. Das Ist jetzt nur zum lernen soweit.... Danke, ich muss das ersteinmal alles ausprobieren ^^ EDIT: Zitat:
|
AW: Bitoperationen
Blättere hier ein paar Seiten zurück und sieh dir meine Beiträge an. Ich habe diesen Typ selber definiert und ausprogrammiert!
Dies musst du natürlich übernehmen |
AW: Bitoperationen
Ich möchte aber nochmals darauf hinweisen, dass der Gebrauch von Bitmasken für Werte, die sich gegenseitig ausschließen (schwarz kann nicht blau und nicht rot sein), nicht oder nur bedingt geeignet ist. Erst wenn es um Wertekombinationen geht ist das dann wieder sinnvoll.
|
AW: Bitoperationen
Hallo,
Zitat:
Zitat:
Delphi-Quellcode:
Ich habe jetzt alles etwas verändert und ... der Text ist dauerhaft rot...
var
i: TBitRange; B: TBitByte; begin for i := 0 to 3 do B[i] := True; Writeln( B.Value, ' - ', B.AsString ); Readln; end.
Delphi-Quellcode:
Wo wir gerade dabei sind:
const
flschwarz = 1; //fl = Flag flblau = 2; flrot = 4; // schreibfehler, vorher stand hier 3 flgruen = 8; flgrau = 16; ... //schwarz klick buchstabe[PositionSpalte,PositionZeile].attribut:=buchstabe[PositionSpalte,PositionZeile].attribut OR 1; //blaun klick buchstabe[PositionSpalte,PositionZeile].attribut:=buchstabe[PositionSpalte,PositionZeile].attribut OR 2; //rot klick buchstabe[PositionSpalte,PositionZeile].attribut:=buchstabe[PositionSpalte,PositionZeile].attribut OR 4; ... //Vergleich if (buchstabe[i,n].Attribut and flschwarz > 0) then Schreibflaeche.Canvas.Font.Color:=clblack; if (buchstabe[i,n].Attribut and flblau > 0) then Schreibflaeche.Canvas.Font.Color:=clblue; if (buchstabe[i,n].Attribut and flrot > 0) then Schreibflaeche.Canvas.Font.Color:=clred; Zitat:
FG Dunkelbunt |
AW: Bitoperationen
Machen wir doch einmal den Vergleich wie im Tutorial (Bit 3 soll anschließend nicht mehr gesetzt sein):
Code:
Du musst also nicht abfragen, ob es vorher gesetzt war, nach der And-Verknüpfung ist es das definitiv nicht mehr.
00000100 //4 ist gesetzt
11111011 //not 4 ------- and-Verknüpfung 00000000 00000000 //4 ist nicht gesetzt 11111011 //not 4 -------- and-Verknüpfung 00000000 |
AW: Bitoperationen
Gut. Und kannst du mir auch erklären, wieso es noch nicht funktioniert? :?
EDIT: Rot ist es nicht mehr, war nen Tippfehler, aber die Farben ändern sich nochimmer nicht... |
AW: Bitoperationen
Vermutlich sind zuviele Bits gesetzt.
[edit] Durch das Verodern setzt Du ja immer ein Bit mehr. Klickst Du jetzt auf schwarz, dann auf blau, dann auf rot, steht 7 in Deiner Zahl, also schwarz, blau und rot. Was soll es denn nun sein? Deshalb ja mein Einwand etwas weiter vorn. [/edit] |
AW: Bitoperationen
Ich gebe jetz mal zur laufzeit den Wert des Bits in einem Label aus um besser zu verstehen, was passiert.
|
AW: Bitoperationen
Du versuchst gerade ein Set nachzubilden und benötigst eigentlich nur ein Enum.
Somit wirkt das alles etwas sinnentleert (wie DeddyH schon angemerkt hat) |
AW: Bitoperationen
Hallo,
ich verstehe, was ihr meint. Auch wenn es vielleicht unsinnig und sinnfrei ist, mach ich erstmal weiter. Eigentlich setzt man doch ein Bit mit:
Code:
Und entfernt es wieder mit:
attribut:= attribut or $01;
Code:
Oder?
attribut := attribut and not $01;
Ich mache das wie folgt: Button1:
Code:
Byte = 1
attribut:= attribut or $01;
attribut := attribut and not $02; Button2:
Code:
Byte = 00000011
attribut:= attribut or $02;
attribut := attribut and not $01; Es müsste doch 00000010 rauskommen!? Fg Dunkelbunt |
AW: Bitoperationen
Du meinst 10 binär? Ja, das sollte eigentlich so sein. Lässt Du Dir auch zum richtigen Zeitpunkt den aktuellen Wert ausgeben?
|
AW: Bitoperationen
Ja ich meine binär.
Ich denke der Zeitpunkt stimmt. Immer wenn ich mit den Pfeiltasten die PositionSpalte bzw PositionZeile bewege wird der Ihalt des Bytes angezeigt, sprich Zeichen und dazugehöriger binärer Wert ... Edit: Ich kenne jetzt den Fehler. Es lag daran, dass zwar die eigentlich Berechnung stimmte, sie aber für das falsche Feld ausgeführt wird. |
AW: Bitoperationen
Ich hab mal schnell ein Beispielprojekt erstellt, da stimmt alles.
Delphi-Quellcode:
procedure TForm5.Button1Click(Sender: TObject);
function ByteToString(b: Byte): string; const BitChars: array [Boolean] of Char = ('0', '1'); var Bit, Posi: Byte; begin SetLength(Result, SizeOf(b) shl 3); Bit := 1; Posi := Length(Result); while Posi > 0 do begin Result[Posi] := BitChars[b and Bit = Bit]; Bit := Bit shl 1; dec(Posi); end; end; var attribut: Byte; begin attribut := 0; attribut := attribut or $01; attribut := attribut and not $02; ShowMessage(ByteToString(attribut)); attribut := attribut or $02; attribut := attribut and not $01; ShowMessage(ByteToString(attribut)); end; |
AW: Bitoperationen
Danke für das Beispiel.
Dein ByteToStr ist echt gut, ich hatte es ein wenig anderst gemacht, aber das ist nicht so wichtig. An dieser Stelle funktioniert alles was funktionieren soll, denke ich. Ich muss jetzt nur noch interne Probleme lösen... Danke auch an die Andere hilfsbereiten DP-Member, Dunkelbunt |
AW: Bitoperationen
Zitat:
Code:
Im Grund hast du ja schon Recht mit dem Entfernen aber du entfernst nicht das gesetzte Bit, sondern das zweite Bit.
// "Eigentlich setzt man doch ein Bit mit:"
attribut:= attribut or $01; // "Und entfernt es wieder mit:" attribut := attribut and not $02; Byte = 1 Sagen wir einmal, Attribut habe den Wert 0. attribut:= attribut or $01 :
Code:
attribut := attribut and not $02;
00000000
or 00000001 ----------- 00000001
Code:
not 2:
2 = 00000010 not 2 = 11111101 00000001 and 11111101 ------------ 00000001 Du erhälts also 1 binär, was 2^0 Dezimals entspricht, |
AW: Bitoperationen
Hallo,
Zitat:
FG Dunkelbunt |
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:28 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz