Autor Beitrag
Passi077
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 125

Win XP
D7 Pers
BeitragVerfasst: Sa 02.10.04 16:05 
Hi,

ich möchte gerne eine Dezimalzahl in Hexadezimal umwandeln.

Dephi bringt da ja einige Funktionen mit um dies zu realisieren. Allerdings möchte ich, dass Delphi so arbeitet, wie man das als Mensch auch machen würde:

255:16=15 Rest 15 = FF

Leider kriege ich das nicht so richtig auf die Reihe. Wenn möglich mit den simpelsten Funktionen, die Delphi zu bieten hat. Hier mal mein bisheriger Code. Dabei wir im Label dann leider immer nur die letzte bzw. erste Hexadezimalziffer angezeigt (d.h. bis 15 funktioniert es..):

ausblenden volle Höhe 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:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
procedure TForm1.Button1Click(Sender: TObject);
    var x: extended;
  var y: integer;
  var z: integer;
  var w: integer;
  var t: integer;
  var i: integer;
begin
label3.Caption := '';
t:=scrollbar1.Position -8;

    for i:=1 to 100 do begin

     label4.Caption := inttostr(t);

    x:=t / 16;

    
  label1.Caption := floattostrf(x,fffixed,0,0);

   y:= strtoint(label1.Caption);
   z:=y*16;
   w:=scrollbar1.Position - z;

  // label3.Caption := inttostr(w);

    if w < 10 then
    label3.Caption := inttostr(w) + label3.Caption
    else if w = 10 then
    label3.Caption := 'A' + label3.Caption
        else if w = 11 then
    label3.Caption := 'B' + label3.Caption
        else if w = 12 then
    label3.Caption := 'C' + label3.Caption
        else if w = 13 then
    label3.Caption := 'D' + label3.Caption
        else if w = 14 then
    label3.Caption := 'E' + label3.Caption
        else if w = 15 then
    label3.Caption := 'F' + label3.Caption;


    if z < 16 then
    break
    else

    t:=y;



    end;


end;


Sobald ich höher gehe bleibt es aber bei einer Ziffer.

Scrollbar1.position ist die Ausgangsdezimalzahl.

Außerdem kommt bei größeren Zahlen ein Fehler, da er diese dann anscheinend mit E rechnet und dies dann keiner Integer-Variable zugewiesen werden kann.

Wo ist der Fehler oder wie kann man das anders mit solch einfachen Mitteln noch realisieren?

Grüße,
Passi


Zuletzt bearbeitet von Passi077 am So 03.10.04 11:57, insgesamt 1-mal bearbeitet
.Chef
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1112



BeitragVerfasst: Sa 02.10.04 16:12 
Gabs letztens erst, mit vollständiger Quelltextlösung: Hier!

Gruß,
Jörg

_________________
Die Antworten auf die 5 häufigsten Fragen:
1. Copy(), Pos(), Length() --- 2. DoubleBuffered:=True; --- 3. Application.ProcessMessages bzw. TThread --- 4. ShellExecute() --- 5. Keine Vergleiche von Real-Typen mit "="!
Passi077 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 125

Win XP
D7 Pers
BeitragVerfasst: Sa 02.10.04 16:35 
Hmmm danke erst mal!

(Hab die Suche benutzt aber nach Hexadezimal gesucht...)

Aber irgendwie ist mir das zu kompliziert um ehrlich zu sein. Das muss für einen absoluten Anfänger sein *g* (keine Funktionen und sowas.. wieso-> haben wir in der Schule noch nicht, da sieht das so aus dem Internet rauskopiert aus).

In Visual Basic hab ich das quasi so hinbekommen wie mit dem oben geposteten Delphi Code. Aber in Delphi läuft das so leider nicht.

Ich verstehe eigentlich auch nicht wieso nicht.

Ich teile erst mal die Dezimalzahl durch 16 und mach auf etwas komplizierte Weise einen Integer draus (+8).

Dann nehme ich die enstandene Zahl mit 16 Mal und ziehe diese dann vom Ausgangwert ab, so dass ich den Rest hab. Den geb ich dann im Label aus.

Dann prüfe ich, ob der Faktor der beim Teilen rausgekommen ist größer als 16 ist und wenn ja setze ich den Ausgangwert zu diesem Faktor und fange von vorne an (desegen die Schleife). Aber wieso packt der das jetzt dann nicht einfach dazu?

Danke nochmal, aber muss einfach noch einfacher gehen, am besten eben so wie ich hier schon angefangen hab..
.Chef
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1112



BeitragVerfasst: Sa 02.10.04 16:47 
So, wie du angefangen hast, ist milde ausgedrückt algorithmischer Unsinn. Ich vereinfache nochmal die Funktion von mir aus dem anderen Thread für Dezimal in Hexadezimal:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
function conv10to16(zahl : integer) : string;
const
  ziffern : array[0..15of Char = ('0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F');
var
  b : Integer;
begin
  Result:='';
  b:=Zahl;
  while b > 0 do
  begin
    Result:=ziffern[b mod 16]+Result;
    b:=b div 16;
  end;
end;

Kommst du damit klar? Wenn nicht, wo genau hängts? (Also bitte kein Kommentar a la "Versteh ich nicht.")

_________________
Die Antworten auf die 5 häufigsten Fragen:
1. Copy(), Pos(), Length() --- 2. DoubleBuffered:=True; --- 3. Application.ProcessMessages bzw. TThread --- 4. ShellExecute() --- 5. Keine Vergleiche von Real-Typen mit "="!
Passi077 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 125

Win XP
D7 Pers
BeitragVerfasst: Sa 02.10.04 17:02 
Ok nochmal Danke!

Dann versuche ich jetzt den Code zu verstehn.

ausblenden Delphi-Quelltext
1:
2:
const  
  ziffern : array[0..15of Char = ('0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F');


Hier lege ich also für das result einfach für '0' '0' fest, für '5' '5', für '11' 'B' etc.? Das er eben das Result einfach von z.B. 1512 in FC umwandelt?

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
  while b > 0 do  
  begin  
    Result:=ziffern[b mod 16]+Result;  
    b:=b div 16;  
  end;


Das verstehe ich nicht wirklich. Er macht das also mal solange bis b <= 0 ist, das is klar.

Aber was macht 'mod'? Und b:=b div 16 teilt also einfach b durch 16?

Also nochmals vielen Dank, wäre echt super wenn Du mir noch den letzten Abschnitt da erklären könntest.

Grüße
Passi
.Chef
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1112



BeitragVerfasst: Sa 02.10.04 17:04 
Passi077 hat folgendes geschrieben:
Aber was macht 'mod'?

Heißt ausgesprochen "modulo" und bildet den Rest einer Division, z.B. 12 mod 5 ergibt 2.

_________________
Die Antworten auf die 5 häufigsten Fragen:
1. Copy(), Pos(), Length() --- 2. DoubleBuffered:=True; --- 3. Application.ProcessMessages bzw. TThread --- 4. ShellExecute() --- 5. Keine Vergleiche von Real-Typen mit "="!
uall@ogc
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1826
Erhaltene Danke: 11

Win 2000 & VMware
Delphi 3 Prof, Delphi 7 Prof
BeitragVerfasst: Sa 02.10.04 17:35 
@chef.
brauchst net noch extra ne variable b anlegen, kannst einfach mit zahl arbeiten :)

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
function conv10to16(zahl : integer) : string
const 
  ziffern : array[0..15of Char = ('0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'); 
begin 
  Result := '';                              // ergebnis = ''
  while zahl > 0 do                          // solange zahl größer als 0 ist mache
  begin 
    Result := ziffern[zahl mod 16]+Result;   // erbegnis := wert aus dem array ziffern
                                             // an der stelle (zahl mod 16)
                                             // mod = rest von (zahl div 16) 
                                             // oder: (zahl - (zahl div 16)*16)
    zahl := zahl div 16;                     // zahl = zahl durch 16
  end
end;
MartinPb
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 698



BeitragVerfasst: Sa 02.10.04 18:01 
Hier die Funktion anders ohne MOD


ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
function conv10to16(zahl : integer) : string;
const
  ziffern : array[0..15of Char = ('0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F');
var
  b, c : Integer;
  s : String;
begin
  Result := '';
  b := Zahl;

  while b > 0 do
  begin
    c := Trunc(((b / 16) - (b div 16)) * 16); // nur den Restwert beachten 
    b := b div 16;

    s := ziffern[c];
    Result:= s + Result;
  end;
end;


Hier wurde auf MOD (Modulo) verzichtet. Wie wird also jetzt c berechnet? Eigentlich genauso wie MOD, nur etwas ausführlicher. Zuerst wird b durch 16 geteilt. Wir haben eine Zahl mit einer Nachkommastelle. Uns interresiert nur die Nachkommastelle. Also ziehen wir von der Zahl den Vorkommawert ab. Das machen wir in dem wir wieder b durch 16 teilen, aber diesmal als Integerberechnung, d.h. ohne Nachkommastellen. Ziehen wir das eine avon dem anderen ab, dann bleibt nur noch der Nachkommawert. Dan multipizieren wir den Wert mit 16, weil wir eingentlich den Reswert der Berechnung haben wollen.

Aber was ist MOD? Beispiel:

Du hast 18 als Dezimalzahl. Den Hexwert kannst du wahrscheinlich auch im Kopf berechnen. In 18 past ein mal 16 und dann bleibt 2 übrich. Und Modulo berechnet dir diese 2.

Wenn du 18 durch 16 teilst, dann hast du 1,125 als Wert. Wir fragen anders: wenn du 18 durch 16 teilst und dich nur interresiert wie oft die 16 in 18 vorkommt, dann stellst du fest, daß es nur ein mal (oder 1). Aber was ist der Rest? Wenn 16 ein mal in 18 past, dann bleibt noch was übrig. Und das was übrig bleibt ist der Modulo Wert. Das kann man verschieden berechnen:

18 MOD 16 = 2

oder

18 / 16 = 1.125 => Rest 0.125 => 0.125 * 16 = 2

oder im Kopf

16 past ein mal in 18. Was übrig bleibt ist 2.

Aber das gleich mit anderen Zahlen:

7 past 3 mal in die 21 oder 21 / 7 = 3. Wir machen es aber schwerer: 20 MOD 7. Jetzt past es nicht mehr 3 sonder nur noch 2 mal. Übrig bleibt 6.

Nochmal:

98 MOD 10. Die 10 past 10 mal in die 100. In die 98 past die 10 nur 9 mal. Übrig bleibt 8. 98 MOD 10 = 8.

Noch fragen?

_________________
Gruß
Martin
.Chef
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1112



BeitragVerfasst: Sa 02.10.04 18:06 
Ich vermute aber mal, dass meine Routine wesentlich schneller ist. Und übersichtlicher. :P

_________________
Die Antworten auf die 5 häufigsten Fragen:
1. Copy(), Pos(), Length() --- 2. DoubleBuffered:=True; --- 3. Application.ProcessMessages bzw. TThread --- 4. ShellExecute() --- 5. Keine Vergleiche von Real-Typen mit "="!
Passi077 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 125

Win XP
D7 Pers
BeitragVerfasst: Sa 02.10.04 19:03 
Ok Danke Leute, ich habe es jetzt Dank div und mod genau so hinbekommen wie ich es wollte:


ausblenden volle Höhe 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:
39:
40:
41:
procedure TForm1.Button1Click(Sender: TObject);
  var x: integer;
  var y: integer;
  var z: integer;
begin
  label1.Caption :='';
z:=strtoint(edit1.Text);

  while z > 15 do
  begin

  y:=z div 16;
  x := z mod 16;

  if x < 10 then
  label1.Caption := inttostr(x) + label1.Caption
  else if x = 10 then label1.Caption := 'A' + label1.Caption
  else if x = 11 then label1.Caption := 'B' + label1.Caption
  else if x = 12 then label1.Caption := 'C' + label1.Caption
  else if x = 13 then label1.Caption := 'D' + label1.Caption
  else if x = 14 then label1.Caption := 'E' + label1.Caption
  else if x = 15 then label1.Caption := 'F' + label1.Caption;
  label2.caption := inttostr(y);

  z:=y;

  if z < 16 then

    if z < 10 then
  label1.Caption := inttostr(z) + label1.Caption
  else if z = 10 then label1.Caption := 'A' + label1.Caption
  else if z = 11 then label1.Caption := 'B' + label1.Caption
  else if z = 12 then label1.Caption := 'C' + label1.Caption
  else if z = 13 then label1.Caption := 'D' + label1.Caption
  else if z = 14 then label1.Caption := 'E' + label1.Caption
  else if z = 15 then label1.Caption := 'F' + label1.Caption;

  ;

 end;
end;



Ich weiß selber dass das nicht die elegante Methode ist, aber das ist eindeutig die simpleste Methode wie man das machen kann würde ich behaupten.

Also vielen Dank für eure Hilfe!

Grüße
Passi


Zuletzt bearbeitet von Passi077 am Sa 02.10.04 19:16, insgesamt 1-mal bearbeitet
MartinPb
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 698



BeitragVerfasst: Sa 02.10.04 19:16 
Die simpelste nicht. Denn anscheinend blickst du nicht durch wie das mit

ausblenden Delphi-Quelltext
1:
  ziffern : array[0..15of Char = ('0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F');					


funktioniert.

Du hast ein Array und dieses ist bereits mit Werten gefüllt. Den passenden Wert kannst du immer mit eine Zahl bekommen. Ist die Zahl 0, dann kriegst du 0. ISt sie 5, dann kriegst du 5. Ist sie 10, dann kriegst du A. Ist sie 15, dann kriegst du F.

Deinen ganzen Spuk mit

ausblenden Delphi-Quelltext
1:
2:
  else if x = 10 then label1.Caption := 'A' + label1.Caption  
  else if x = 11 then label1.Caption := 'B' + label1.Caption


kannst du mit dem Array lösen.

ausblenden Delphi-Quelltext
1:
label1.Caption := ziffern[x] + label1.Caption					


Den Rest hast du noch doppelt gemacht. Ist die Zahl irgendwann kleiner 16, dann liefert MOD auch diese Zahl korrekt. 11 MOD 16 = 11, weil die 16 null mal in die 11 passt. Der Rest ist dann 11.

Du brauchst also kein extra Block für den wert unter 16.

_________________
Gruß
Martin
uall@ogc
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1826
Erhaltene Danke: 11

Win 2000 & VMware
Delphi 3 Prof, Delphi 7 Prof
BeitragVerfasst: Sa 02.10.04 21:11 
Chef. meine ist schneller :D
.Chef
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1112



BeitragVerfasst: Sa 02.10.04 21:21 
Da würde ich an deiner Stelle nicht drauf wetten. Vielleicht hat ja der Compiler die zusätzliche Variable rausoptimiert, die ich da reingemacht hab. MEIN GOTT, man möge mir verzeihen ... eine Unkonzentriertheit ... abgelenkt ... und das mir ... es wird nie wieder vorkommen ... VERSPROCHEN! :shock: :? :bawling:











:D 8) Alles nur Spaß ...

_________________
Die Antworten auf die 5 häufigsten Fragen:
1. Copy(), Pos(), Length() --- 2. DoubleBuffered:=True; --- 3. Application.ProcessMessages bzw. TThread --- 4. ShellExecute() --- 5. Keine Vergleiche von Real-Typen mit "="!
Passi077 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 125

Win XP
D7 Pers
BeitragVerfasst: So 03.10.04 11:56 
Jo ok das mit dem Array ist wirklich noch einfacher und die Abfrage unter 16 kann man tatsächlich weglassen.

Also nochmal vielen Dank an alle!
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: So 03.10.04 20:08 
MartinPb hat folgendes geschrieben:
ausblenden Delphi-Quelltext
1:
    c := Trunc(((b / 16) - (b div 16)) * 16); // nur den Restwert beachten					

Zu dieser Berechnung hätte ich auch mal noch nen Hinweis:
Geht auch ohne FloatingPoint-Mathe:
ausblenden Delphi-Quelltext
1:
c := b - 16 * (b div 16);					

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
Coder
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1383
Erhaltene Danke: 1

WinXP
D2005 PE
BeitragVerfasst: So 03.10.04 20:24 
Hehe, und wieder ein neuling der den Fragenstatus nicht kennt. (logisch)
Ihr solltet echt mal einen Hinweis machen. :wink:
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: So 03.10.04 20:49 
Ist schon in Planung ... zumindest wollte sich TUFKAPL (AKA Christian S.) drum kümmern. ;-)

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.