Entwickler-Ecke

Sonstiges (Delphi) - Dualzahlen in Hex-zahlen umwandeln - Datentypen-Problem)


rob87 - Mi 23.01.08 11:31
Titel: Dualzahlen in Hex-zahlen umwandeln - Datentypen-Problem)
Hallo,
auch ich hab mich dem Thema angenommen, die Datentypen Hexadezimal, Dual und Dezimal untereinander umzurechnen. :D :D

Nun hab ich allerdings ein kleines Problem bez. meines Datentyps. Vll. kann da mal einer drüberschauen:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
procedure Tfrmzahlenwandeln.dual_hexadezimal();
const
  hex_zahlen = '0123456789ABCDEF';
var
  eingabe : String;
  i, ergebnis : Integer;
begin

  eingabe := Edit1.Text;    <-- Edit1 ist das Eingabefeld

  if Length(eingabe)>4 then
    ShowMessage('Fehler: Überlauf');
  if (Length(eingabe)=0or (StrToIntDef(eingabe,-1)=-1then
    ShowMessage('Bitte eine Zahl eingeben');

      ergebnis:=0;
      Edit2.Text := '0';    <-- Edit2 ist das Ausgabefeld

  for i:=1 to Length(eingabe) do
  begin
    ergebnis:=ergebnis*2;
    ergebnis:=ergebnis+StrToInt(eingabe[i]);
  end;

  //Starte ganz hinten
  i:=length(text);
  repeat
    eingabe:='';
    repeat
      eingabe:=text[i]+eingabe;
      Dec(i);  
    until (i=0or (Length(eingabe)=4);
    //Dem Ergebnis das Hexadezimalzeichen hinzufügen
    ergebnis := hex_zahlen[StrToInt(eingabe)+1]+ergebnis;  <-- Fehler: "Inkompatible Typen"
  until i=0;
  Edit2.Text := IntToStr(ergebnis);

end;


rob87 - Mi 23.01.08 15:08

Kann mir denn niemand helfen? :shock: :roll:


Horschdware - Mi 23.01.08 15:14

schnell drübergeflogen:

ergebnis ist ein integer, hex_zahlen ein string.
integer + string = ?


Xentar - Mi 23.01.08 15:19

3 1/2 Stunden - nun sei doch mal ungeduldig :P

Gibt es einen Grund, dass du die Eingabe nicht erst in einen Integer umwandelst (sollte noch relativ einfach gehen) und dann mit IntToHex ausgibst?


rob87 - Mi 23.01.08 15:31

Zitat:
3 1/2 Stunden - nun sei doch mal ungeduldig

Sorry, zwecks der Ungeduld. :wink:

Und nein, es gibt keinen speziellen Grund. Der einzige Grund wäre, dass ich die function IntToHex nicht kenn??

Gibts da noch mehr davon? IntToBinar oder HexToInt?? Sind die alle standardmäßig includiert?

Und wie schaut da dann mein Programm aus? Dann kann ich ja den Quellcode der Function um 90% kürzen?


Xentar - Mi 23.01.08 16:03

user profile iconrob87 hat folgendes geschrieben:
Gibts da noch mehr davon? IntToBinar oder HexToInt?? Sind die alle standardmäßig includiert?

Und wie schaut da dann mein Programm aus? Dann kann ich ja den Quellcode der Function um 90% kürzen?


1. Eine Umwandlung Binär <> Integer ist mir nicht bekannt. Lässt sicher relativ leicht selber schreiben.
Meine Idee, für eine Umwandlung Binär > Integer:
Du läufst den Binärstring von hinten nach vorne durch. Ein Merker gibt den aktuellen Stellenwert an (fängt also bei 1 an, und verdoppelt sich jedesmal). Wenn im Binärstring eine '1' steht, addierst du den Merker auf den Integer, ansonsten passiert gar nichts.

2. HexToInt: nö, gibts nicht - man verwende StrToInt('$' + MeinHexWert); Das '$' vorneweg sagt Delphi, dass das nachfolgende als Hex-Wert betrachtet werden soll.

3. Viel Spaß beim ausprobieren ;)


Fiete - Mi 23.01.08 16:23

Moin rob87,

es gibt IntToHex - Standard

IntToBin - in der Unit IdGlobal

HexToInt wie folgt:

Delphi-Quelltext
1:
2:
3:
4:
function HexToInt(HexNum: string): Integer; 
begin 
  Result:=StrToInt('$' + HexNum); 
end;


BinToInt - ist mir nichts bekannt.

z.B.

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
function BinToInt(Value: string): Integer;
var
  i, iValueSize: Integer;
begin
  Result := 0;
  iValueSize := Length(Value);
  for i := iValueSize downto 1 do
    if Value[i] = '1' then Result := Result + (1 shl (iValueSize - i));
end;



Gruß
Fiete


rob87 - Mi 23.01.08 16:42

Vielen Dank für die reichlichen Infos.

Ich test des alles heut und morgen mal. Da fragt ma sich, warum da noch einer so Funktionen selber macht.
:D :D

Ich meld mich dann wieder ;-)


rob87 - Do 24.01.08 08:57

Ok.Nochmals vielen Dank für die reichlichen Infos.

Nun zur Auswertung: *g*

Also Dual -> Hex geht zwar schon, bringt aber falsches Ergebnis??

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
var
  zahl : Integer;
begin
  zahl := StrToInt(Edit1.Text);

  try
    Edit2.Text := IntToHex(zahl,0);
  except
    messagedlg('Fehler bei der Verarbeitung - Bitte wiederholen',mtWarning,[mbOK], 0);
  end;
end;


Und dann bin ich noch auf der Suche nach Hex->Dual.

Ich dacht mir einerseits ich könnt einfach zuerst die Funktion hex->dez und dann dez -> bin aufrufen. Aber da macht er momentan noch den Fehler, dass er behauptet, ein "D" (beispielsweise) sei kein gültiger Integer-Wert, womit er leider Recht hat. :D
Aber auch da muss ich auch nochmal drüberschauen


user profile iconFiete hat folgendes geschrieben:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
function BinToInt(Value: string): Integer;
var
  i, iValueSize: Integer;
begin
  Result := 0;
  iValueSize := Length(Value);
  for i := iValueSize downto 1 do
    if Value[i] = '1' then Result := Result + (1 shl (iValueSize - i));
end;


Funktioniert wunderbar. Habs halt bissal abgewandelt. Aber danke ;) Ich kannte z.B. den Aufruf "Length()" nicht. Und was machst du genau mit: + (1 shl (iValueSize - i))


Xentar - Do 24.01.08 10:21

user profile iconrob87 hat folgendes geschrieben:
Ok.Nochmals vielen Dank für die reichlichen Infos.

Nun zur Auswertung: *g*

Also Dual -> Hex geht zwar schon, bringt aber falsches Ergebnis??

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
var
  zahl : Integer;
begin
  zahl := StrToInt(Edit1.Text);

  try
    Edit2.Text := IntToHex(zahl,0);
  except
    messagedlg('Fehler bei der Verarbeitung - Bitte wiederholen',mtWarning,[mbOK], 0);
  end;
end;


Und dann bin ich noch auf der Suche nach Hex->Dual.

Ich dacht mir einerseits ich könnt einfach zuerst die Funktion hex->dez und dann dez -> bin aufrufen. Aber da macht er momentan noch den Fehler, dass er behauptet, ein "D" (beispielsweise) sei kein gültiger Integer-Wert, womit er leider Recht hat. :D
Aber auch da muss ich auch nochmal drüberschauen


Zu ersterem: Ja, isr klar, dass die Ergebnisse falsch sind.
wenn du eine binäre 4 einträgst, macht die Funktion StrToInt daraus eine 100, weil sie nicht weiß, dass der String als Binärzahl zu verstehen ist.
Such mal nach einer Funktion BinToInt.

2. Jo, "D" ist kein Integer - aber ein Hex-Wert. Und wie weiter oben schonmal angedeutet: Schreib ein '$' (Dollar Zeichen) davor, dann weiß Delphi, dass es sich um einen Hex-Wert handelt. Dann klappts auch mit dem D ;)


rob87 - Do 24.01.08 11:08

user profile iconXentar hat folgendes geschrieben:

Zu ersterem: Ja, isr klar, dass die Ergebnisse falsch sind.
wenn du eine binäre 4 einträgst, macht die Funktion StrToInt daraus eine 100, weil sie nicht weiß, dass der String als Binärzahl zu verstehen ist.
Such mal nach einer Funktion BinToInt.


Hab ich. Und hab herausgefunden, dass es sogar eine Funktion BinToHex gibt, was ja noch besser wäre. Allerdings komm ich mit der Syntax ned so zurecht. Da spielt auch noch ein PChar eine Rolle und das verwirrt mich etwas:
Google-Ergebnis zu BinToHex [http://www.delphipraxis.net/topic45408.html]

------------------

Und zu 2) (Hex -> Bin) Da gibts auch eine eigene Funktion HexToBin. AUch wieder mit PChar :-(

Denn wenn ich deine Variante machen würd, müsst ich die Funktionen
hexadezimal_dezimal() und dezimal_dual() verändern. Und dass will ich eigentlich nicht.

---------------------------

Die ganze Wandlerei von PChar zu String und zurück verwirrt mich... :roll:


jaenicke - Do 24.01.08 11:25

Hier gibts auch noch ein Beispiel zu BinToHex (und HexToBin):
http://delphi.about.com/library/rtl/blrtlBinToHex.htm


rob87 - Do 24.01.08 11:29

user profile iconjaenicke hat folgendes geschrieben:
Hier gibts auch noch ein Beispiel zu BinToHex (und HexToBin):
http://delphi.about.com/library/rtl/blrtlBinToHex.htm


Vielen Dank. Ich hab grad auf der selben Seite die analoge Beschreibung für die andere Richtung der Konvertierung gefunden :wink:

Is ziemlich trocken, aber ich versuch des mal irgendwie zu verstehen...


rob87 - Do 24.01.08 11:46

Der Code auf der Seite delphi.about.com\... [http://delphi.about.com/library/rtl/blrtlBinToHex.htm] is ja Wahnsinn. ALso ich blick da nicht durch.

Kann mir des jemand kurz erklären, oder anhand von einem oder meinem Beispiel zeigen??
Wäre super!


oldmax - Do 24.01.08 14:36

Hi
Die Umwandlung ist relativ einfach und die Mathematik auch.
Binär
teile die Ganzzahl solange durch 2 bis die Zahl 0 ist. Der Rest ist entweder 1 oder 0.
Selbiges trifft für die Hex-Zahl zu, nur das du die Ganzzahl durch 16 teilen mußt und der Rest kommt in den String.
Wenn du einen String mit '01' oder '0123456789ABCDEF' vorbesetzt, kannst du direkt die Restzahl + 1 als Zeiger auf den vorbesetzten String nehmen, und das so gefundene Zeichen in den Rückgabe-String der Funktion
Dadurch hast du 2 fast gleiche Functions...


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
Function IntToBin(IntWert : Integer):String;
Var Ref              : String;
    Calc              : Integer;
    Zeiger            : Integer;
    Ausg             : String;
Begin
   Ausg:='';
    Ref:='01';
  Calc:=Wert;
   Repeat
      Zeiger:=Calc-(Trunc(Calc/2)*2)+1// Rest aus der Teilung ermitteln und da rest 0 oder 1 ist für Zeiger +1
      Ausg:=Ref[Zeiger]+Ausg;
      Calc:=Trunc(Trunc/2); 
   until Calc:=0// ende der Berechnung
   While Length(Ausg) (*) 16 then Ausg:='0'+Ausg; // Auf Wortlänge bringen, bzw. anpasen auf gewünschte Länge
   Result:=Ausg;
end;


(*) hier kommt ein kleiner Zeichen hin, geht bei mir nich, vermutlich die Tastatur.....
Diese Function ist für Hex-Zahlen leicht anzuassen. Einfach den Ref-String verlängern und den übergebenen Wert durch 16 teilen. (alle 2en mit 16 ersetzen) Auch die Ausgabelänge in der While-Schleife ist anzupassen und Result:='$'+Ausg; bringt die Hex-Zahl zum Ausdruck.

Nun zur Rückwandlung. Von Hex nach Int ist gar kein Problem, weil wie schon gesagt durch voranstellen von $ der Wert als Zahl erkannt wird. Anders ist es bei binären Werten Da aber auch hier die Mathemetik bekanntlich 2^ 0 bis 2^n ist, kann auch hier eine einfache Function geschrieben werden:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
FunctionBinToInt(BinaerWert : String):Integer;
Var     Calc              : Integer;
          i                    : Integer;
         
Begin
   Calc:=0;
   For i:=0 to Length(Wert) -1 do 
  begin
     if BinaerWert[ Length(Wert)-i]='1' then Calc:=Calc+Power(2,i); // 2^0 =1, 2^1=2, 2^2=4 etc.....
  end;
   Result:=Ausg;
end;


Wer jetzt den nötigen Ehrgeiz hat, der kann natürlich auch eine eigene Hex nach Int-Function schreiben..
Da kommt bei Power (16,i-1) rein und das ganze muß natürlich mit StrToInt('$'+Char) multipliziert werden.
Also auch keine Hexerei....
Und nu mach mal Oktalzahlen ... vor und zurück......
Gruß oldmax


rob87 - Do 24.01.08 15:17

Also meine Funktion für Hex -> Bin ist nun folgende:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
var
  zahl, ergebnis : String;
  int_wert : integer;
begin
  zahl := Edit1.Text;
  int_wert := StrToInt('$' + zahl);

  if int_wert = 0 then
    Edit2.Text := '0';

  ergebnis := IntToStr(int_wert mod 2);

  repeat
    int_wert := int_wert div 2;
    ergebnis := IntToStr(int_wert mod 2)+ergebnis;
  until int_wert = 0;

  Edit2.Text := ergebnis;
end;


Bin -> Hex folgt (hoffentlich bald :D)

Add Bin -> Hex:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
var
  int_wert, i, laenge : Integer;
  inhalt, ergebnis : String;
begin
  inhalt := Edit1.Text;
  int_wert := 0;
  laenge := Length(inhalt);

  for i := laenge downto 1 do
    if inhalt[i] = '1' then int_wert := int_wert + (1 shl (laenge - i));

  ergebnis := IntToHex(int_wert,0);
  edit2.Text := ergebnis;
end;


------------------------

<Thread gelöst> Ich hoffe, dass dieser Beitrag noch vielen Leuten helfen kann und bedanke mich für die Mithilfe... ;) :wink: