Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Zahl in einzelne Stellen zerlegen ohne Stringkonvertierung! (https://www.delphipraxis.net/133112-zahl-einzelne-stellen-zerlegen-ohne-stringkonvertierung.html)

richard_boderich 25. Apr 2009 23:34


Zahl in einzelne Stellen zerlegen ohne Stringkonvertierung!
 
Hallo zusammen!

Ich hätte da mal eine Frage an die Runde. Ich habe eine 3- stellige Zahl sagen wir mal die z.B. die "123".
Ich möchte diese Zahl jetzt gerne zerlegen. und zwar in ihre 1-ner , 10-ner und 100-ter Stelle. Undzwar wenn möglich
elegant und ohne Stringconvertierung (und Zerlegung in einzelne Chars).

Also so...

123 = 1 100'er Stelle
= 2 10' Stelle
= 3 1' Stelle

Das kann man ja auch so ausdrücken

-> 1*10^2 + 2*10^1 + 3*10^0

so kann man die Zahl erzeugen, aber ich habe grad gar keine Idee wie man zurückrechnen könnte.
Hat da jemand eine Idee?

Dax 26. Apr 2009 00:18

Re: Zahl in einzelne Stellen zerlegen ohne Stringkonvertieru
 
Mal nicht direkt in Delphi, sonder eher funktional. Aber das Prinzip sollte klar werden ;)
Code:
function toDigits (0) = []
function toDigits (number) = concat(toDigits (number / 10), listOf(number mod 10))

DeddyH 26. Apr 2009 08:46

Re: Zahl in einzelne Stellen zerlegen ohne Stringkonvertieru
 
Spontan fallen mir da auch 2 Möglichkeiten ein:
Delphi-Quellcode:
function Stellenwert(Zahl: integer; Stelle: byte): integer;
begin
  Result := trunc(Zahl / Power(10,Pred(Stelle))) mod 10;
  //oder
  Result := trunc(frac(Zahl / Power(10,Stelle)) * 10);
end;
Stelle ist dann "von rechts" anzugeben, also 1 für die 1er-Stelle, 2 für die 10er-Stelle usw.

alzaimar 26. Apr 2009 09:25

Re: Zahl in einzelne Stellen zerlegen ohne Stringkonvertieru
 
Und sukkzessives Zerteilen geht so:
Delphi-Quellcode:
Function NumberToDigits (aNumber : Cardinal) : TByteArray;
Var
  n : Integer;

Begin
  n := 0;
  SetLength (Result, 10);
  While aNumber <> 0 do Begin
    Result[n] := aNumber mod 10;
    aNumber := aNumber div 10;
    Inc (n);
  End;
  SetLength (Result, n + 1);
End;
..
// Beispiel
Var
  B : TByteArray;

Begin
  B := NumberToDigits (1234); // --> B = (4,3,2,1), also B[0] = 4, B[1] = 3 usw
Dann hast Du in einem Abwasch gleich die ganze Zahl unterteilt.

DeddyH 26. Apr 2009 09:29

Re: Zahl in einzelne Stellen zerlegen ohne Stringkonvertieru
 
Angeber :tongue:. Aber dann würde ich das Array zumindest als Parameter übergeben, um dem Grundsatz genüge zu tun, dass man Speicher auf der Ebene freigeben soll, auf der er angefordert wurde.

himitsu 26. Apr 2009 10:01

Re: Zahl in einzelne Stellen zerlegen ohne Stringkonvertieru
 
jetzt könnte man noch auf ASM umsteigen (IDIV = DIV + MOD zugleich)

PS: wegen des Speichers ... da kümmert sich Delphi drum, also isses "egal", da du dich nicht ums Freigeben kümmern mußt :angel2:

Amateurprofi 26. Apr 2009 10:54

Re: Zahl in einzelne Stellen zerlegen ohne Stringkonvertieru
 
Zitat:

Zitat von alzaimar
Und sukkzessives Zerteilen geht so:
Delphi-Quellcode:
Function NumberToDigits (aNumber : Cardinal) : TByteArray;
Var
  n : Integer;

Begin
  n := 0;
  SetLength (Result, 10);
  While aNumber <> 0 do Begin
    Result[n] := aNumber mod 10;
    aNumber := aNumber div 10;
    Inc (n);
  End;
  SetLength (Result, n + 1);
End;
..
// Beispiel
Var
  B : TByteArray;

Begin
  B := NumberToDigits (1234); // --> B = (4,3,2,1), also B[0] = 4, B[1] = 3 usw
Dann hast Du in einem Abwasch gleich die ganze Zahl unterteilt.


@alzaimar:
In der letzten Zeile von NumberToDigits sollte es wohl besser heißen
Delphi-Quellcode:
SetLength (Result, n);

richard_boderich 26. Apr 2009 11:11

Re: Zahl in einzelne Stellen zerlegen ohne Stringkonvertieru
 
@alzaimar

Leider bekomme ich unter Delphi 7 die Fehlermeldung inkompatible Typen bei den Setlength Zuweisungen?!

himitsu 26. Apr 2009 11:23

Re: Zahl in einzelne Stellen zerlegen ohne Stringkonvertieru
 
nimm mal statt TByteArray ein TByteDynArray :angel:


[add]
Delphi-Quellcode:
Uses Types; // für TByteDynArray

Function NumberToDigits(Number: Cardinal): TByteDynArray;
  Var n: Integer;

  Begin
    SetLength(Result, 10);
    n := 0;
    ASM
      PUSH EDI
      MOV  EDI, &Result
      MOV  EDI, [EDI]
      MOV  ECX, 10
      MOV  EAX, &Number
      @@Loop:
      XOR  EDX, EDX
      IDIV ECX
      MOV  [EDI], DL
      INC  EDI
      INC  &n
      TEST EAX, EAX
      JNZ  @@Loop
      POP  EDI
    End;
    SetLength(Result, n);
  End;

richard_boderich 26. Apr 2009 12:10

Re: Zahl in einzelne Stellen zerlegen ohne Stringkonvertieru
 
besten Dank himi! Es funktionopelt prächtig :)


Alle Zeitangaben in WEZ +1. Es ist jetzt 04:51 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz