![]() |
"Zeichen" im Integer
Wie kann man am schnellsten an die Länge eines Integers kommen, ohne Kommazahlen zu benutzen?
|
Re: "Zeichen" im Integer
meinst du wieviele Ziffern eine Integer Zahl hat?
anzziffern:=length(inttostr(zahl)); aber ist nicht so grad die feine mathematische Art ;) |
Re: "Zeichen" im Integer
Moin Fabian,
ein integer ist auf einem 32-Bit-System immer 4 Byte lang. |
Re: "Zeichen" im Integer
Ein Interger ist immer 4 Byte lang. Oder was verstehst du unter "Länge eines Integer"? Ich befrage mal meine Glaskugel und die meint du willst die Anzahl der Ziffern einer Zahl wissen. Bitte vor dem Posten etwas nachdenken, was man eigentlich will und / oder wo konkret das Problem ist. Dann kann man auch die Frage gescheit formulieren. Meist ergibst sich dann schon von selbst die Lösung, wenn man mal etwas darüber nachgedacht hat.
|
Re: "Zeichen" im Integer
Du meinst die Länge der String-Repräsentation des Integers?
Würd ich so machen:
Delphi-Quellcode:
Müsste klappen.
function GetStrToIntLength(x: Integer): Integer;
begin if x<0 then begin Result:=1; x:=abs(x); end else Result:=0; while x>0 do begin x:=x div 10; inc(Result); end; end; |
Re: "Zeichen" im Integer
Okay... Also das meinet ich nicht @ Seehase :D
Ich meinte, wie viele Ziffern ein Integer ohne die führenden Nullen hat. (Ich hoffe jetzt ist es verständlich :D) z.B. 12345 wäre dann 5 als Ergebnis @ Antigo: So geht es, aber ist es schnell genug? |
Re: "Zeichen" im Integer
Zitat:
Vor allem: wozu brauchst du diese Information, wenn man fragen darf? |
Re: "Zeichen" im Integer
Tut mir leid, ich verstehe überhaupt nicht, was Du willst - vor allem, weil Du bei integer auf einmal von Kommazahlen sprichst. Du bist ja nicht "neu im Geschäft"; deshalb nehme ich an, Du meinst nicht:
Delphi-Quellcode:
Folgendes dürfte ziemlich langsam sein:
iLaenge := SizeOf(integer);
Delphi-Quellcode:
Ich würde es vermutlich so machen:
iLaenge := Length(IntToStr(iZahl));
Delphi-Quellcode:
Ich vermute, dass einer der Fachleute für ASM oder Bit-Manipulation eine schnellere Lösung kennt. Jürgen
function AnzahlZiffern(const iZahl: int): integer;
var i0: integer; begin Result := 1; i0 := iZahl div 10; while (i0 >= 0) do begin Inc(Result); i0 := i0 div 10; end; end; PS. Bitte nicht sauer sein, wenn ich mit C#-Schreibweisen durcheinander gekommen bin. PS2. Das war ja klar, dass ich langsam bin; aber meine Antwort ist noch nicht überflüssig. |
Re: "Zeichen" im Integer
wie wärs mit dem 10er Logarithmus?
Delphi-Quellcode:
uses math;
{...} function GetDigitLength(x: integer): integer; begin if x <> 0 then result := trunc(1+Log10(abs(x))); end; |
Re: "Zeichen" im Integer
Zitat:
Und bei der Berechnung möchte ich auf Kommazahlen verzichten. Zitat:
Würde es mir die Bitgröße (= 4 Byte) wiedergeben=? Folgendes dürfte ziemlich langsam sein:
Delphi-Quellcode:
iLaenge := Length(IntToStr(iZahl));
Zitat:
Zitat:
Zitat:
Zitat:
Ich sehe schon... Ich werde das mit den Methoden versuchen... und Testen wer schnell ist und wer nicht... |
Re: "Zeichen" im Integer
Ich nehme mal an, auch mit Assembler wird es nicht recht viel schneller gehen. Das einzige, was man hier ausnutzen kann, ist diese Schweinerei mit cdq, bringt aber auch nicht recht viel, wenn überhaupt was.
Delphi-Quellcode:
function NumberLength(x: Integer): Integer;
asm push ebx mov ebx, 10 cdq mov ecx, edx and ecx, 1 xor eax, edx sub eax, edx @loop: and eax, eax jz @endloop mov edx, 0 div ebx add ecx, 1 jmp @loop @endloop: mov eax, ecx pop ebx end; |
Re: "Zeichen" im Integer
Ich wuerde sagen, die staendige Division ist eine unnoetige Bremse, die man nicht zwingend braucht.
Algorithmisch gesehen sollte das die schnellste Variante sein:
Delphi-Quellcode:
Ich hab leider keinen Delphicompiler installiert, aber ich sehe eigentlich keinen grund, warums nich laufen sollte ;)
function DecIntLength(x: integer): byte;
const m: packed array[0..9] of integer = ($A, $64, $3E8, $2710, $186A0, $F4240, $989680, $5F5E100, $3B9ACA00, $0); asm MOV EAX, x MOV ESI, m CDQ XOR EAX, EDX AND EDX, 1 ADD EAX, EDX @@loopstart: INC DL MOV EBX, [ESI] TEST EBX, EBX JZ loopend CMP EBX, EAX JA loopend ADD ESI, 4 JMP loopstart @@loopend: MOV AL, DL end; greetz Mike [Edit] and is schneller als sets, also her damit ;) [Edit2] und den test brauchma auch ned... hoff ich zumindest mal *g* |
Re: "Zeichen" im Integer
Und das ganze jetzt für den Int64 :D
Ein Problem in deinem Code :D Zitat:
Delphi-Quellcode:
MOV ESI, m
|
Re: "Zeichen" im Integer
Jason, warum schreibst du statt $A, $64,... nicht einfach 10, 100,...? Zur Verwirrung? :lol:
|
Re: "Zeichen" im Integer
Zitat:
Na ja, das mit dem Array hatte dann auch zur folge, dass dann das geschriebene nichmehr kompiliert... warum auch immer Delphi was dagegen hat, nen Zeiger in ein 32-Bit-Register zu schreiben :gruebel: Egal, es geht auch ohne assembler:
Delphi-Quellcode:
function DecIntLength(x: integer): byte;
const m: packed array[0..9] of integer = (10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000, 0); var i: byte; begin result := 0; i := 0; if (x < 0) then begin inc(result); x := -x; end; repeat inc(i); until ((m[i] = 0) or (m[i] > x)) inc(result, i); end; Zitat:
Delphi-Quellcode:
Wie gesagt: nicht probiert...
m: packed array[0..17] of integer = (10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000, 10000000000, 100000000000, 1000000000000, 10000000000000, 100000000000000, 1000000000000000, 10000000000000000, 100000000000000000, 0);
greetz Mike |
Re: "Zeichen" im Integer
ich hab mal ein bißchen rumgetestet, auch mit assembler, bisher aber nur für 32bit integer.
Delphi-Quellcode:
das ist dabei rausgekommen, sehr ähnlich zu jason's asm funktion, nur ohne irgendwelche schleifen.
function InlineAsm(x:integer) : integer;
const e=1; z=10; h=100; t=1000; zt=10000; ht=100000; m=1000000; zm=10000000; hm=100000000; md=1000000000; zmd=10000000000; asm MOV EDX, EAX JMP @Ret1 @Ret1 : CMP EDX,z JAE @Ret10 MOV EAX, 1 JMP @Ende; @Ret10 : CMP EDX,h JAE @Ret100 MOV EAX, 2 JMP @Ende; @Ret100 : CMP EDX,t JAE @Ret1000 MOV EAX, 3 JMP @Ende; @Ret1000 : CMP EDX,zt JAE @Ret10000 MOV EAX, 4 JMP @Ende; @Ret10000 : CMP EDX,ht JAE @Ret100000; MOV EAX, 5 JMP @Ende; @Ret100000 : CMP EDX,m JAE @Ret1000000 MOV EAX, 6 JMP @Ende; @Ret1000000 : CMP EDX,zm JAE @Ret10000000 MOV EAX, 7 JMP @Ende; @Ret10000000 : CMP EDX,hm JAE @Ret100000000 MOV EAX, 8 JMP @Ende; @Ret100000000 : CMP EDX,md JAE @Ret100000000 MOV EAX, 9 JMP @Ende; @Ret1000000000 : MOV EAX, 10 JMP @Ende; @Ende : end; ich hab jason's asm funktion nicht getestet, aber seine delphi funktion, die war extrem schnell(7-8mal schneller als die asm funktion von 3_of_8). ich hatte das gefühl, dass meine funktion einen tick schneller ist als die delphi funktion von jason(ich glaub nicht mal 1%) |
Alle Zeitangaben in WEZ +1. Es ist jetzt 18:24 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 by Thomas Breitkreuz