Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Aus Integer-Wert bestimmte Stelle extrahieren (https://www.delphipraxis.net/95431-aus-integer-wert-bestimmte-stelle-extrahieren.html)

ibp 6. Jul 2007 11:09


Aus Integer-Wert bestimmte Stelle extrahieren
 
Hallo,

stehe gerade voll auf dem schlauch :gruebel:

Situation:

ich habe einen integer-wert int=0101125 und ich brauche z.b. die 10er stelle (hier =2).

gibt es da ne einfache möglichkeit uasser irgendwelche 10er berechnungen?

thx schon mal

Dax 6. Jul 2007 11:11

Re: Aus Integer-Wert bestimmte Stelle extrahieren
 
Wie wärs denn mit
Delphi-Quellcode:
wert div Round(IntPow(10, stelle-1)) mod 10

ibp 6. Jul 2007 11:19

Re: Aus Integer-Wert bestimmte Stelle extrahieren
 
ja das wollte ich eigentlich vermeiden. kann man nicht direkt irgendwie auf das bit zugreifen?

scrat1979 6. Jul 2007 11:20

Re: Aus Integer-Wert bestimmte Stelle extrahieren
 
Zitat:

Zitat von ibp
Hallo,

stehe gerade voll auf dem schlauch :gruebel:

Situation:

ich habe einen integer-wert int=0101125 und ich brauche z.b. die 10er stelle (hier =2).

gibt es da ne einfache möglichkeit uasser irgendwelche 10er berechnungen?

thx schon mal

Du könntest auch die Zahl mittels "StringVariable := IntToStr(integer-variable);" in einen STring konvertieren, danach kannst Du mit StringVariable[i] auf die einzelnen Ziffern zugreifen...

SCRaT

//EDIT: Roter Kasten :-) Was Deine zweite Frage angeht bin ich leider überfragt - sorry.

ibp 6. Jul 2007 11:22

Re: Aus Integer-Wert bestimmte Stelle extrahieren
 
@scrat

danke aber das ist nicht wirklich performant :wink:

scrat1979 6. Jul 2007 11:25

Re: Aus Integer-Wert bestimmte Stelle extrahieren
 
Schon klar, aber von dieser Vorraussetzung war ja nicht die Rede. Es hieß ja nur "einfache Möglichkeit" *ggg* :lol:

Im Ernst: DA kann ich Dir leider nicht weiterhelfen. Vielleicht hat ja jemand einen asm-Code, der dürfte auch relativ schnell sein...

Viel Glück noch!


SCRaT

Dax 6. Jul 2007 11:31

Re: Aus Integer-Wert bestimmte Stelle extrahieren
 
Die Möglichkeit auf "Bits" zuzugreifen besteht leider nicht - ein Digit eines Int-Wertes in Dezimaldarstellung belegt ca 3,331 Bit. Außer dem vorgeschlagenen Weg geht wohl nichts so einfach..

phreax 6. Jul 2007 13:35

Re: Aus Integer-Wert bestimmte Stelle extrahieren
 
Hallo ibp,
probier mal das hier:

müsste eigentlich recht perfomant sein, jedenfalls performanter als die string version... ;)
Delphi-Quellcode:
function GetDigit(Int, Digit: Integer): Integer;
begin
 Result := Int Mod (Digit * 10);
 if digit > 10 then
 Result := Result- (Int mod (Digit div 10));
 Result := Result div Digit;
end;

//Beispielaufruf
  ShowMessage(inttostr(GetDigit(0101125,10)));
Digit muss die Stelle sein also zum Bsp 10er 100er usw...


mfg phreax

SirThornberry 6. Jul 2007 13:54

Re: Aus Integer-Wert bestimmte Stelle extrahieren
 
was genau hast du vor. anhand folgender Aussage bin ich etwas verwirrt:
Zitat:

ich habe einen integer-wert int=0101125
Was hat dich dazu bewegt eine führende 0 anzugeben? Hat das einen Grund? Denn ein reiner Integer merkt sich nicht wieviel führende Nullen angezeigt werden sollen.

ibp 6. Jul 2007 14:01

Re: Aus Integer-Wert bestimmte Stelle extrahieren
 
@sir vergiss die führende 0 war ein tippfehler beim kloppen auf den nummernblock!

@phreax schau dir mal das beispiel von dax an, die hat nur 4 operationen ;-)

sirius 6. Jul 2007 14:09

Re: Aus Integer-Wert bestimmte Stelle extrahieren
 
Zitat:

Zitat von ibp
@sir vergiss die führende 0 war ein tippfehler beim kloppen auf den nummernblock!

@phreax schau dir mal das beispiel von dax an, die hat nur 4 operationen ;-)

:gruebel: 4 Operationen?

Intpower und Round sind Funktionen. Besonders Intpower, rechnet nicht nur in der FPU, was alleine schon länger dauert, sondern dort auch noch ne Menge Operationen. Und Round benutzt auch die interne FPU "round"-Funktion.

Edit:
Die ASM-Variante
Delphi-Quellcode:
function getdigit(zahl,stelle:integer):integer;
asm
  push ebx

  xor ecx,ecx
  inc ecx
  xor ebx,ebx
  mov bl,10

@while:
  dec edx
  jl @endwhile
  imul ecx,10
  jmp @while
@endwhile:

  cdq
  div ecx
  cdq
  div ebx
  mov eax,edx

  pop ebx
end;

phreax 6. Jul 2007 14:27

Re: Aus Integer-Wert bestimmte Stelle extrahieren
 
Zitat:

Zitat von sirius
:gruebel: 4 Operationen?

Intpower und Round sind Funktionen. Besonders Intpower, rechnet nicht nur in der FPU, was alleine schon länger dauert, sondern dort auch noch ne Menge Operationen. Und Round benutzt auch die interne FPU "round"-Funktion.

dito!

mfg phreax

ibp 6. Jul 2007 15:29

Re: Aus Integer-Wert bestimmte Stelle extrahieren
 
kleiner hinweis...
Zitat:

Zitat von ibp
...10er stelle (hier=2)...

also phreax methode braucht die stellen al 1er,10er,100er... um von den vorliegenden stellen 1,2,3 auf eben solche zu kommen brauchst du eine weitere berechnung, eben die der power :wink:

war vielleicht ein wenig ungünstig beschrieben. also die stellen sind vorhanden als 1,2,3.. usw.

sirius 6. Jul 2007 15:40

Re: Aus Integer-Wert bestimmte Stelle extrahieren
 
Zitat:

Zitat von ibp
war vielleicht ein wenig ungünstig beschrieben. also die stellen sind vorhanden als 1,2,3.. usw.

Meine Funktion beschreibt die Stellen mit 0,1,2,3
Also muss noch ein "dec edx" irgendwo vor @while

ibp 6. Jul 2007 15:56

Re: Aus Integer-Wert bestimmte Stelle extrahieren
 
@sirius da ich leider des asm nicht mächtig bin, könntest du es mir bitte erklären was da genau passiert?

SirThornberry 6. Jul 2007 16:01

Re: Aus Integer-Wert bestimmte Stelle extrahieren
 
bei der vem von phreax verwendeten Aufruf geht es auch noch so (ohne if):
Delphi-Quellcode:
function GetDigit(Int, Digit: Integer): Integer;
begin
  result := Int mod (Digit * 10) div Digit;
end;
Wenn man also von 101125 die 5 haben will muss man 1 übergeben, wenn man die 2 haben will 10, wenn man die 0 haben will 10000.

ibp 6. Jul 2007 16:10

Re: Aus Integer-Wert bestimmte Stelle extrahieren
 
Zitat:

Zitat von SirThornberry
...Wenn man also von 101125 die 5 haben will muss man 1 übergeben, wenn man die 2 haben will 10, wenn man die 0 haben will 10000.

so sollte es eben nicht sein ;-) siehe hier

sirius 6. Jul 2007 16:20

Re: Aus Integer-Wert bestimmte Stelle extrahieren
 
mit kleinen Änderungen
Delphi-Quellcode:
function getdigit(zahl,stelle:integer):integer;
{
 in
 zahl  --> eax
 stelle --> edx

 out
 result <-- eax
}
asm
  push ebx  //ebx auf den Stack retten

  xor ecx,ecx //ecx löschen
  inc ecx    //ecx auf 1 setzen
  mov ebx,10  //ebx auf 10 setzen

@while:        //nur ein Label für Sprungziele
  dec edx      //edx um 1 erniedrigen
  jng @endwhile //wenn edx nicht größer als 0 nach @endwhile springen
  imul ecx,10   //ecx mit 10 multiplizieren
  jmp @while   //nach @while springen
@endwhile:

  cdq          //convert DWord-->QWord (Division vorbereiten)
  div ecx      //division von eax/ecx --> ganzzahliger Anteil in eax; Rest in edx
  cdq          //dasselbe nochmal
  div ebx      //division von eax/ebx   (Rest steht wieder in edx)
  mov eax,edx  //edx nach eax(=Result)

  pop ebx      //gerettetes Register wieder herstellen
end;
Bis endwhile ist die Vorbereitung dass aus 1,2,3,4 -->1,10,100,1000 wird. Ab dem CDQ macht die funktion das, was Sirthornberry auch macht.
Es geht halt nicht ohne, dass man erst die 10er-Potenzen ausrechnet.

alzaimar 6. Jul 2007 16:49

Re: Aus Integer-Wert bestimmte Stelle extrahieren
 
So würde ich das machen, wenn ich unbedingt die Stelle angeben will...
Delphi-Quellcode:
Function GetDigit (anInteger, aDigit : Integer) : Integer;
Begin
  Case aDigit of
     1 : Result := anInteger Mod 10;
     2 : Result := (anInteger Div 10) Mod 10;
     3 : Result := (anInteger Div 100) Mod 10;
     4 : Result := (anInteger Div 1000) Mod 10;
     5 : Result := (anInteger Div 10000) Mod 10;
     6 : Result := (anInteger Div 100000) Mod 10;
     7 : Result := (anInteger Div 1000000) Mod 10;
     8 : Result := (anInteger Div 10000000) Mod 10;
     9 : Result := (anInteger Div 100000000) Mod 10;
   else Result := 0 // Mehr Stellen hat ein INTEGER nicht (und wenn doch: einfach erweitern)
  End
End;
Das dürften -grob geschätzt- 2 Operationen und ein paar Vergleiche (Case of) sein. Schneller ginge es(?) nur mit einer Sprungtabelle. Weiterhin spart man eine Multiplikation ggü der vorherigen Version.

Macci 31. Aug 2007 13:56

Re: Aus Integer-Wert bestimmte Stelle extrahieren
 
Hallo,

hab gerade diesen Thread gelesen. Mit meiner Lösung ist eine superschnelle Berechnung möglich. Vielleicht braucht es ja noch jemand ;-)

Delphi-Quellcode:
function GetDecimalDigit(number,digit:Integer):ShortInt;
asm

MOV ECX, @table.Pointer[EDX*4]

CDQ
IDIV ECX
CDQ
MOV ECX, 10
IDIV ECX

MOV AL, DL

{Die folgenden 3 Zeilen können einkommentiert werden,
wenn NEGATIVE Zahlen auch unterstützt werden sollen,
so dass das Ergebnis trotzdem eine positive Zahl ist.
Also wenn z.B. GetDecimalDigit(-3210,1) = 1 sein soll,
und NICHT GetDecimalDigit(-3210,1) = -1, NUR dann die
3 folgenden Zeilen einkommentieren!
(Geschwindigkeitsverlust von ca. 12% !!) }

//CBW
//XOR AL, AH
//SUB AL, AH

RET

@table:
DD 1,10,100,1000,10000,100000
DD 1000000, 10000000, 100000000, 1000000000
end;


Zum Testen kann folgender Code verwendet werden.

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var a,b,c:int64;i:integer;
begin
QueryPerformanceFrequency(a);
QueryPerformanceCounter(b);

for i:=1 to 10000000 do GetDecimalDigit(6543210,3);

QueryPerformanceCounter(c);

ShowMessage('10 Mio. Berechnungen benötigten: '+  IntToStr((c - b) * 1000 div a) + ' Millisekunden, '
           + 'eine Berechnung benötigte: '+ IntToStr((c - b) * 100 div a) + ' Nanosekunden.');

end;
Viele Grüße,
Mac

ibp 3. Sep 2007 17:43

Re: Aus Integer-Wert bestimmte Stelle extrahieren
 
hab mal alle einen performance test unterzogen...

Code:
----------------------------------------------
alzaimars Lösung... [je 100 Mio Berechnungen]
1. Stelle:1465 Millisekunden
2. Stelle:3371 Millisekunden
3. Stelle:3313 Millisekunden
4. Stelle:3312 Millisekunden
5. Stelle:3312 Millisekunden
----------------------------------------------
Maccis Lösung... [je 100 Mio Berechnungen]
1. Stelle:3314 Millisekunden
2. Stelle:4930 Millisekunden
3. Stelle:3295 Millisekunden
4. Stelle:3295 Millisekunden
5. Stelle:3295 Millisekunden
----------------------------------------------
sirius Lösung... [je 100 Mio Berechnungen]
1. Stelle:3400 Millisekunden
2. Stelle:3399 Millisekunden
3. Stelle:3755 Millisekunden
4. Stelle:4314 Millisekunden
5. Stelle:4769 Millisekunden
----------------------------------------------
phreaxs Lösung... [je 100 Mio Berechnungen]
1. Stelle:3873 Millisekunden
2. Stelle:4073 Millisekunden
3. Stelle:3850 Millisekunden
4. Stelle:4074 Millisekunden
5. Stelle:4076 Millisekunden
----------------------------------------------
Daxs Lösung... [je 100 Mio Berechnungen]
1. Stelle:6561 Millisekunden
2. Stelle:9490 Millisekunden
3. Stelle:9826 Millisekunden
4. Stelle:9843 Millisekunden
5. Stelle:9804 Millisekunden

to-wer 30. Dez 2017 14:47

AW: Aus Integer-Wert bestimmte Stelle extrahieren
 
10 Jahre später sind es nur noch ca. 700 Millisekunden statt 3313 von alzaimers...
:lol:

Mikkey 31. Dez 2017 14:09

AW: Aus Integer-Wert bestimmte Stelle extrahieren
 
Zitat:

Zitat von to-wer (Beitrag 1389885)
10 Jahre später sind es nur noch ca. 700 Millisekunden statt 3313 von alzaimers...
:lol:

Das ist eigentlich ziemlich ernüchternd. Früher(R) gab es in zehn Jahren beeindruckendere Leistungssteigerungen.

LTE5 31. Dez 2017 14:12

AW: Aus Integer-Wert bestimmte Stelle extrahieren
 
Zitat:

10 Jahre später sind es nur noch ca. 700 Millisekunden statt 3313 von alzaimers...
So kann man das auch nicht sagen. Wenn ihr beiden einen absolut baugleichen PC habt, dann ja. Ansonsten ist der Vergleich für die Katz.

Delphi-Laie 31. Dez 2017 15:21

AW: Aus Integer-Wert bestimmte Stelle extrahieren
 
Zitat:

Zitat von Mikkey (Beitrag 1389966)
Zitat:

Zitat von to-wer (Beitrag 1389885)
10 Jahre später sind es nur noch ca. 700 Millisekunden statt 3313 von alzaimers...
:lol:

Das ist eigentlich ziemlich ernüchternd. Früher(R) gab es in zehn Jahren beeindruckendere Leistungssteigerungen.

Das haben asymptotische Annäherungen, i.d.R. durch exponentielle Verläufe bedingt, so an sich.

Gibt es z.B. auch im Umweltschutz. Simples Beispiel: Angenommen, für einen bestimmten Aufwand läßt sich die Hälfte der Schadstoffe entfernen. Für den gleichen Aufwand (meistens sogar noch mit größerem) läßt sich dann aber nicht der Rest der Schadstoffe entfernen, sondern wiederum nur die Hälfte dessen, was noch vorhanden ist. So sind nach der ersten Reinigung noch 50%, nach der zweiten noch 25% (und leider eben nicht 0%) der Schadstoffe enthalten.

Um mal wieder die Kurve zur Programmierung zu bekommen: Auch bei der Eliminierung der Programmierfehler kommt man zumindest bei größeren Projekten dehalb kaum auf völlige Fehlerfreiheit.

Insofern halte ich diesen kritischen ("ernüchternden") Unterton für unberechtigt.


Alle Zeitangaben in WEZ +1. Es ist jetzt 23:25 Uhr.

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