![]() |
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 |
Re: Aus Integer-Wert bestimmte Stelle extrahieren
Wie wärs denn mit
Delphi-Quellcode:
wert div Round(IntPow(10, stelle-1)) mod 10
|
Re: Aus Integer-Wert bestimmte Stelle extrahieren
ja das wollte ich eigentlich vermeiden. kann man nicht direkt irgendwie auf das bit zugreifen?
|
Re: Aus Integer-Wert bestimmte Stelle extrahieren
Zitat:
SCRaT //EDIT: Roter Kasten :-) Was Deine zweite Frage angeht bin ich leider überfragt - sorry. |
Re: Aus Integer-Wert bestimmte Stelle extrahieren
@scrat
danke aber das ist nicht wirklich performant :wink: |
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 |
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..
|
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:
Digit muss die Stelle sein also zum Bsp 10er 100er usw...
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))); mfg phreax |
Re: Aus Integer-Wert bestimmte Stelle extrahieren
was genau hast du vor. anhand folgender Aussage bin ich etwas verwirrt:
Zitat:
|
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 ;-) |
Re: Aus Integer-Wert bestimmte Stelle extrahieren
Zitat:
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; |
Re: Aus Integer-Wert bestimmte Stelle extrahieren
Zitat:
mfg phreax |
Re: Aus Integer-Wert bestimmte Stelle extrahieren
kleiner hinweis...
Zitat:
war vielleicht ein wenig ungünstig beschrieben. also die stellen sind vorhanden als 1,2,3.. usw. |
Re: Aus Integer-Wert bestimmte Stelle extrahieren
Zitat:
Also muss noch ein "dec edx" irgendwo vor @while |
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?
|
Re: Aus Integer-Wert bestimmte Stelle extrahieren
bei der vem von phreax verwendeten Aufruf geht es auch noch so (ohne if):
Delphi-Quellcode:
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.
function GetDigit(Int, Digit: Integer): Integer;
begin result := Int mod (Digit * 10) div Digit; end; |
Re: Aus Integer-Wert bestimmte Stelle extrahieren
Zitat:
![]() |
Re: Aus Integer-Wert bestimmte Stelle extrahieren
mit kleinen Änderungen
Delphi-Quellcode:
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.
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; Es geht halt nicht ohne, dass man erst die 10er-Potenzen ausrechnet. |
Re: Aus Integer-Wert bestimmte Stelle extrahieren
So würde ich das machen, wenn ich unbedingt die Stelle angeben will...
Delphi-Quellcode:
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.
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; |
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:
Viele Grüße,
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; Mac |
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 |
AW: Aus Integer-Wert bestimmte Stelle extrahieren
10 Jahre später sind es nur noch ca. 700 Millisekunden statt 3313 von alzaimers...
:lol: |
AW: Aus Integer-Wert bestimmte Stelle extrahieren
Zitat:
|
AW: Aus Integer-Wert bestimmte Stelle extrahieren
Zitat:
|
AW: Aus Integer-Wert bestimmte Stelle extrahieren
Zitat:
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 17:50 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz