Autor Beitrag
christoph
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 28

Win XP(SPack1),Win 2000(Spack3)
Delphi 6(Spack2)
BeitragVerfasst: Mo 10.03.03 18:38 
Hi allerseits wie kann man eiine Dezimal Zahl zerlegen?? Also ich habe Zahl(Typ Single) vom wert 0,0 bis 200,0. Ich möchte das jetzt jeder einzel wert (in einen Integerwert gewandelt wird...

Also bei der Zahl 199,1 sollte das dann so aussehen
Integer1 =1
Integer2 =9
Integer3 =9
Integer4 =1

Wir kann man das in Dlphi verwirklichen ??

Vielen Dank für eure Hilfe schon mal im Vorraus.
Gruss Christoph
derDoc
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 623

Win Vista Prof
D2007 Prof
BeitragVerfasst: Mo 10.03.03 18:53 
Ich würde umständlich erst deine Zahl in eine String verwandeln und dann den String in ein array of String zerschneiden. Zum Schluss jeden Teil des Arrays wieder in einen Integer umwandeln.

_________________
MfG derDoc
There are only 10 types of people: those who understand binary and those who don't.
Popov
ontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic starofftopic star
Beiträge: 1655
Erhaltene Danke: 13

WinXP Prof.
Bei Kleinigkeiten D3Pro, bei größeren Sachen D6Pro oder D7
BeitragVerfasst: Mo 10.03.03 20:29 
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
var
  i, k: Integer;
  s: String;
begin
  k := 199.1;
  s := IntToStr(Trunc(k));
  for i := 1 to Length(s) do ListBox1.Items.Add(s[i]);
end;


Ungeprüft

Ich hab die einzelnen Zahlen in eine ListBox eingefügt.

Moderiert von user profile iconKlabautermann: Code- durch Delphi-Tags ersetzt

_________________
Popov
Christian S.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 20451
Erhaltene Danke: 2264

Win 10
C# (VS 2019)
BeitragVerfasst: Di 11.03.03 15:40 
@Popov: Deinen Quelltext verstehe ich nicht. Mit Trunc verlierst Du aber doch Stellen, oder?

So könnte man es machen:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
ziffern : ARRAY OF Integer;

implementation

{$R *.dfm}

procedure ziffern_suchen (zahl : Single);
VAR my_zahl : Integer;
begin
  while Trunc(zahl) <> zahl do zahl:=zahl*10;
  my_zahl :=Trunc(zahl);

  SetLength(ziffern,0);
  repeat
    SetLength(ziffern,Length(ziffern)+1);
    ziffern[High(ziffern)]:=(my_zahl mod 10);
    my_zahl:=my_zahl div 10;
  until my_zahl = 0;
end;


Du musst das Array dann nur noch einmal umkrempeln, damit Du die richtige Reihenfolge hast.

MfG,
Peter

Moderiert von user profile iconKlabautermann: Code- durch Delphi-Tags ersetzt

_________________
Zwei Worte werden Dir im Leben viele Türen öffnen - "ziehen" und "drücken".
Udontknow
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2596

Win7
D2006 WIN32, .NET (C#)
BeitragVerfasst: Di 11.03.03 16:13 
Hier mal meine Variante (ohne Umkrempeln... :wink: ):

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
ziffern : ARRAY OF Integer; 

procedure ziffern_suchen (zahl : Single); 
VAR str:String
var i:integer;
begin 
  //Zahl in Str umwandeln
  Str:=FloatToStr(Zahl);

  //Komma herausnehmen
  Str:=StringReplace(Str,',','');

  //Grösse des Arrays festlegen
  SetLength(ziffern,Length(Str));

  //Array bestücken
  for i:=1 to Length(Str) do
    ziffern[i-1]:=StrToint(Str[i]);
end;

Cu, :)
Udontknow

Moderiert von user profile iconKlabautermann: Code- durch Delphi-Tags ersetzt
Christian S.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 20451
Erhaltene Danke: 2264

Win 10
C# (VS 2019)
BeitragVerfasst: Di 11.03.03 16:35 
Also, da das Array extrem klein bleiben wird, haben wir wohl kaum ein Speicher Problem. Die Geschwindigkeit habe ich mit diesem Quelltext getestet.

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:
procedure ziffern_suchen (zahl : Single);
VAR my_zahl,i : Integer;
    my_ziffern : Array of Integer;
begin
  while Trunc(zahl) <> zahl do zahl:=zahl*10;
  my_zahl :=Trunc(zahl);

  SetLength(my_ziffern,0);
  repeat
    SetLength(my_ziffern,Length(my_ziffern)+1);
    my_ziffern[High(my_ziffern)]:=(my_zahl mod 10);
    my_zahl:=my_zahl div 10;
  until my_zahl = 0;

  SetLength(ziffern,Length(my_ziffern));
  for i:=High(my_ziffern) TO 0 DO
  ziffern[High(ziffern)-i]:=my_ziffern[i];
end;


procedure ziffern_suchen_mit_str (zahl : Single);
VAR str:String;
var i:integer;
begin
  //Zahl in Str umwandeln
  Str:=FloatToStr(Zahl);

  //Komma herausnehmen
  Str:=StringReplace(Str,',','',[]);

  //Grösse des Arrays festlegen
  SetLength(ziffern,Length(Str));

  //Array bestücken
  for i:=1 to Length(Str) do
    ziffern[i-1]:=StrToint(Str[i]);
end;

procedure TForm1.Button1Click(Sender: TObject);
VAR zahl : Real;
    zeit1,zeit2,zeit,i : Integer;
begin
  zahl:=2.147483647;
  zeit1:=GetTickCount;
  for i:=0 TO 999999 DO ziffern_suchen(zahl);
  zeit2:=GetTickCount;
  ShowMessage(IntToStr(zeit2-zeit1));
  zeit1:=GetTickCount;
  for i:=0 TO 999999 DO ziffern_suchen_mit_str(zahl);
  zeit2:=GetTickCount;
  ShowMessage(IntToStr(zeit2-zeit1));
end;


Und da ist meiner schneller! Ätsch! :wink:

Aber mal ehrlich: ich würde Deinen Algorithmus nehmen, denn die paar paar Millisekunden, die meiner schneller ist, tausche ich gerne gegen die Übersichtlichkeit Deines Algorithmus' ein!

MfG,
Peter

<edit>Du hast editiert! Das ist gemein! </edit>

Moderiert von user profile iconKlabautermann: Code- durch Delphi-Tags ersetzt

_________________
Zwei Worte werden Dir im Leben viele Türen öffnen - "ziehen" und "drücken".
Popov
ontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic starofftopic star
Beiträge: 1655
Erhaltene Danke: 13

WinXP Prof.
Bei Kleinigkeiten D3Pro, bei größeren Sachen D6Pro oder D7
BeitragVerfasst: Di 11.03.03 17:04 
Peter Lustig hat folgendes geschrieben:
@Popov: Deinen Quelltext verstehe ich nicht. Mit Trunc verlierst Du aber doch Stellen, oder?


Jo. Ich hab wieder mal falsch gelesen und verstanden, daß der Wert vorher in einen Integer gewandelt wird.

Dann sieht mein Code so aus:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
var 
  i: Integer;
  s: String;
begin
  s := FloatToStr(199.1);
  for i := 1 to Length(s) do if s[i] in ['0'..'9'then ListBox1.Items.Add(s[i]);
end;


Da ich D3 habe kenne ich mich nicht mit dynamische Arrays kaum aus, deshalb ListBox1. Aber ich versuch es mal:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
var
  i: Integer;
  s: String;
  x: array of Integer;
begin
  s := FloatToStr(199.1);
  for i := 1 to Length(s) do if not(s[i] in ['0'..'9']) then Delete(s, i, 1);

  SetLength(x, Length(s)-1);
  for i := 1 to Length(s) do x[i-1] := StrToInt(s[i]);
end;


In x[0] ist der erste Wert.

Alternativ könnte man in x[0] die MaxLänge reinschreinen. Der Vorteil wäre, daß man weiß welche Werte echt sind. Das würde dann so aussehen:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
var
  i: Integer;
  s: String;
  x: array of Integer;
begin
  s := FloatToStr(199.1);
  for i := 1 to Length(s) do if not(s[i] in ['0'..'9']) then Delete(s, i, 1);

  SetLength(x, Length(s)+1);
  x[0] := Length(s);

  for i := 1 to Length(s) do x[i] := StrToInt(s[i]);
end;


Jetzt ist in x[1] ist der erste Wert.

Moderiert von user profile iconKlabautermann: Code- durch Delphi-Tags ersetzt

_________________
Popov
Udontknow
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2596

Win7
D2006 WIN32, .NET (C#)
BeitragVerfasst: Di 11.03.03 17:30 
@Peter Lustig:

Menno! :? :mrgreen: Dafür funzt mein Algo auch mit Zahlentypen, die nicht zu Integer zuweisungskompatibel sind. :) HCSTÄ!

Ich hatte mal irgendwo gelesen, daß, wenn man oft dynamischen Arrays neue Grössen gibt, es zu einer unnötigen Speicherreservierung kommt.

In diesem Falle reservierst du erst 4 Byte für einen Integerwert. Danach änderst du aber die Grösse auf 2 Integerwerte. Delphi muss nun fü den Array erneut vom Betriebssystem Speicher anfordern (und zwar für 8 Byte). Nun befindet sich der Array also an einem anderen Speicherbereich. Das ist aber noch lange kein Grund für Delphi, den vorigen Speicherbereich (der 4Byte groß war) an das Betriebssystem zurückzugeben. Stattdessen verweilt es in der Obhut eines Speicher-Managers, der im späteren Verlauf des Programmes diese 4 Byte für irgendetwas anderes zuteilen kann.
Delphi nimmt sich im Falle einer 5-Ziffer-Zahl also nicht 5*4 Byte an Speicher, sondern 1*4+2*4+3*4+4*4+5*4=(1+2+3+4+5)*4=60 Byte.

Für so kleine Dimensionen ist es natürlich irrelevant, ich habe aber schon Konstellationen gesehen, wo sich Programme über 300 MB Speicher zogen, nur weil die dynamische Größe von Arrays (oder auch TList-Instanzen, siehe Capacity) nicht einmal am Anfang, sondern immer wieder gestückelt erhöht wurde.

Das mit dem Speicher konnte ich nun leider nicht reproduzieren, aber die Leistung (Geschwindigkeit) einer Anwendung ist natürlich um einiges besser, wenn nur weniger Speicherzuweisungen erfolgen.

Cu, :)
Udontknow
Christian S.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 20451
Erhaltene Danke: 2264

Win 10
C# (VS 2019)
BeitragVerfasst: Di 11.03.03 17:52 
@Udontknow:
Hm, ich sehe, dass das sehr schnell zu einem Problem werden kann. Ich habe eine Art Hybrid aus Deinem und meinem Algorithmus gemacht. Er ist jetzt schneller als mein Erster und müllt den Speicher nicht mehr zu:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
procedure ziffern_suchen_hybrid (zahl : Single);
VAR my_zahl,i : Integer;
    my_ziffern : Array of Integer;
begin
  while Trunc(zahl) <> zahl do zahl:=zahl*10;
  my_zahl :=Trunc(zahl);

  SetLength(my_ziffern,Length(IntToStr(my_zahl))); //<-- da ist die Änderung
  repeat
    my_ziffern[High(my_ziffern)]:=(my_zahl mod 10);
    my_zahl:=my_zahl div 10;
  until my_zahl = 0;

  SetLength(ziffern,Length(my_ziffern));
  for i:=High(my_ziffern) TO 0 DO
  ziffern[High(ziffern)-i]:=my_ziffern[i];
end;


Folgendes ist jetzt die Rangliste der Geschwindigkeit:
die Mischung von udontknow's und meinem
mein erster
popovs
udontknow's

MfG,
Peter

MfG,
Peter

Moderiert von user profile iconKlabautermann: Code- durch Delphi-Tags ersetzt

_________________
Zwei Worte werden Dir im Leben viele Türen öffnen - "ziehen" und "drücken".
Udontknow
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2596

Win7
D2006 WIN32, .NET (C#)
BeitragVerfasst: Di 11.03.03 18:28 
Na gut, da muss ich wohl nachziehen: :wink:

ausblenden 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:
procedure ziffern_suchen_mit_str2 (zahl : Single);
VAR str:String;
var i,j:integer;
var Laenge:Integer;
begin
  //Zahl in Str umwandeln
  Str:=FloatToStr(Zahl);

  //Laenge bestimmen
  Laenge:=Length(Str);
  if Pos(',',Str)>0 then
    Dec(Laenge);

  //Array-Laenge festlegen
  SetLength(Ziffern,Laenge);

  //Array bestücken
  j:=0;
  for i:=1 to Laenge do
  begin
    if Str[i]=',' then
      Continue;
    Ziffern[j]:=Ord((Str[i]))-48;
    Inc(j);
  end;
end;


BTW: Interessant ist, daß die zweite Prozedur langsamer ist, als wenn sie alleine läuft... :?:

Cu,
Udontknow

Moderiert von user profile iconKlabautermann: Code- durch Delphi-Tags ersetzt
christoph Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 28

Win XP(SPack1),Win 2000(Spack3)
Delphi 6(Spack2)
BeitragVerfasst: Di 11.03.03 22:49 
Himmel da hab ich aber ne Flut von Antworten bekommen..
Also erstmal ein riesen Dank für die Ganzen Antworten Hammer!!!!!
Hier nun mal mein Code.....
Wie gesagt zur erinnerung ich wollte ja jeweils dei einzelen Zahlen haben
nur ob das jetzt länger oder schneller geht wie euer Code müsste man testen....

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
procedure TForm1.Button1Click(Sender: TObject);
var
i1,i2,i3,i4,i5:word;
i             :Integer;
Zahl          :single;
begin
Zahl :=(strtofloat(Nummer.Text)*10);
i    :=trunc(zahl); 
divmod(i,10000,i1,i2);
Nr1.Value := i2;
 divmod(i,1000,i2,i3);
Nr2.Value := i3;
 divmod(i,100,i3,i4);
Nr3.Value := i4;
 divmod(i,10,i4,i5);
Nr4.Value := i5;
 end;


Grüsse Chris

Moderiert von user profile iconKlabautermann: Code- durch Delphi-Tags ersetzt


Zuletzt bearbeitet von christoph am Fr 14.03.03 01:36, insgesamt 3-mal bearbeitet
derDoc
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 623

Win Vista Prof
D2007 Prof
BeitragVerfasst: Do 13.03.03 10:10 
Ich glaube die Geschwindigkeitsunterschiede sind im geringen Bereich, dein Code sollte da aber ganz gut abschneiden. Wenn er läuft kannst du ihn doch benutzen. Die Millisekunden machen die Sau nicht fett.

_________________
MfG derDoc
There are only 10 types of people: those who understand binary and those who don't.