![]() |
Dezimal nach Dual umwandeln
OK, eigentlich trivial das Thema. Nehmen wir die Zahl 175 als Beispiel. Mit Papier und Bleistift würde man es so machen:
Code:
Dieser Algorithmus nach Delphi umgesetzt könnte so aussehen:
175
175 : 2 = 87 Rest 1 87 : 2 = 43 Rest 1 43 : 2 = 21 Rest 1 21 : 2 = 10 Rest 1 10 : 2 = 5 Rest 0 5 : 2 = 2 Rest 1 2 : 2 = 1 Rest 0 1 : 2 = 0 Rest 1 10101111
Delphi-Quellcode:
(Das Writeln und das Sleep dienen nur zur Veranschaulichung.) Dies entspricht so ziemlich einer eins zu eins Umsetzung, wie man es auch im Kopf machen würden.
function dec2bin1(Value: Cardinal): String;
const s = '%d : %d = %d Rest %d'; var Rest: Cardinal; IntPart: Cardinal; Temp: Cardinal; begin Temp := Value; IntPart := Value; while IntPart > 0 do begin Rest := IntPart mod 2; // Divisionsrest IntPart := Temp div 2; // ganzahlige Division writeln(Format(s, [Temp, 2, IntPart, rest])); Temp := IntPart; result := IntToStr(rest) + result; Sleep(175); end; end; Jetzt kann man das Ganze aber noch, sagen wir mal, rein mathematisch machen:
Delphi-Quellcode:
Doch da habe ich ein Verständnis Problem:
function dec2bin2(Int: Integer): String;
var i : Integer; begin Result := ''; for i := 7 downto 0 do Result := Result + IntToStr((Int shr i) and 1); end; Warum läuft die Schleife von 7 runter auf 0? Und was macht das ((Int shr i) and 1? Was der Operator shr macht ist mir bekannt: Aus 101 wird 010, wenn man das um eins nach rechts verschiebt. Aber warum macht man das und warum die logische Verknüpfung mit and 1? Desweiteren: nehmen wir die Zahl 1234567890 als Beispiel. dec2bin1 liefert 1001001100101100000001011010010. dec2bin2 aber nur 11010010. Also die ersten acht Stellen bzw. so viele Stellen, wie die Schleife durchlaufen wird. |
Re: Dezimal nach Dual umwandeln
Ohne jetzt die function dec2bin2 getestet zu haben, würde ich sagen:
Du testet den Integer vom Bit 7 bis Bit 0. ((int shr 7)AND 1) testet Bit7 auf 1 und ergibt ein Boolean. Mit AND-Verkünpfungen kann man Integerwerte auf gesetzte Bits testen. z.b:
Code:
in Dec2Bin2 testest du quasi das Bit 0 auf 1 oder 0.
5 AND 1 = 1
0101 (=5) AND 0001 (=1) -------------- = 0001 (=1) //oder 5 AND 4 = 4 0101 (=5) AND 0100 (=4) -------------- = 0100 (=4) // oder 5 AND 2 = 0 0101 (=5) AND 0010 (=2) --------- = 0000 (=0) Die Schleife läuft runter von 7 auf 0 um die Reihenfolge der Einsen und Nullen im Result-String beizubehalten.
Delphi-Quellcode:
sollte genauso funktionieren.
for i := 0 to 7 do
Result := IntToStr((Int shr i) and 1) + Result; Wenn du größere Zahlen als 65535 testen willst, muß du für die For-Schleife die Anzahl der zu testenden Bits ermitteln. |
Re: Dezimal nach Dual umwandeln
Zunächst möchte ich mal meine Variante euch nicht vorenthalten, ist eine Vereinfachung des ersten Codes:
Delphi-Quellcode:
Zum zweiten Code:
function DecToBin(Value: Cardinal): String;
begin repeat Result := IntToStr(Value mod 2) + Result; Value := Value div 2; until Value = 0; end; Es liegt einfach daran, dass die Schleife von 7 auf 0 runterläuft und somit nur die rechten 8 Bits behandelt werden. Man müsste also vorher die Anzahl der benötigten Bits berechnen (bei Cardinal maximal 32 :zwinker: ) und dann die Schleife z.B. von 31 auf 0 runter laufen lassen. Das funktioniert, getestet! Die führenden Nullen dann zum Schluss noch zu entfernen sollte wohl nicht das Problem sein. //Edit: Die Anzahl der benötigten Bits zu berechnen ist ja eigentlich ganz einfach, so spart man sich auch das Entfernen der überflüssigen Nullen. Die FOR-Schleife müsste also wie folgt abgeändert werden:
Delphi-Quellcode:
for i := Floor(Log2(Value)) downto 0 do
|
Re: Dezimal nach Dual umwandeln
Guten Morgen.
Die Zahl der führenden Nullen kann man auch anders ermitteln. Und die Zahl der Speicheranforderungen durch schrittweises Vergrößern des Result-Strings lässt sich vermeiden:
Delphi-Quellcode:
Grüße vom marabu
function DualToStr(c: Cardinal): String;
const MAXLEN = 32; var i: Integer; begin SetLength(Result, MAXLEN); i := 0; repeat Inc(i); Result[MAXLEN - i] := Chr(Ord('0') + Ord(Odd(c))); c := c shr 1; until c = 0; Result := Copy(Result, MAXLEN - i, Succ(i)); end; |
Re: Dezimal nach Dual umwandeln
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 20:31 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