35-stelligen Integer in String konvertieren



  • Hallo Jungs,

    ich habe ein echtes Problem und zwar brauche ich Konvertierungsmöglichkeiten für eine 35-stellige (zur Basis 10) Zahl.

    Ich brauche IntToStr, StrToInt und ein Inc. Das Problem ist, dass mir die Idee dazu fehlt eine Zahl zu konvertieren, die mehr als 8 Byte Speicherplatz benötigt.

    Solange es sich um Q/DWORD handelt ist es per Modulodivision durch 10 ja kein Problem an die einzelnen Stellen zu kommen und dann mit 48 zu addieren, um die Konvertierung zum String zu erhalten. Alles darüber hinaus bereitet mir Kopfschmerzen.

    Das Problem abstrahiert auf einen kleineren Wertebereich:
    1 Byte hat den beispielsweiße den Wert 1111 1111, also 255. Wenn ich angenommen nur eine Wortbreite von 8 Bit hätte, wäre ich nicht in der Lage das nächste Byte so einfach mit dem zu addieren. Ich würde also "255" ausgeben.
    Angenommen das nächste Byte hat das erste Bit gesetzt ... schon entsteht ein Problem, denn die Zahl (angenommen Sie ist ein 2 Byte Typ) lautet nun 511 ...

    Ich hoffe ihr versteht was ich meine. Hat jemand eine Idee?



  • inc funktioniert auf dem string ganz gut. nach rechts gehen und while((*p--)++=='9');

    die konvertierungsfunktiobnen verstehe ich nicht, denn den 35-stelligen int würde ich als string speichern und int2string tut ja dann gar nicht sein.



  • -ups-



  • volkard schrieb:

    inc funktioniert auf dem string ganz gut. nach rechts gehen und while((*p--)++=='9');

    Das Problem ist, dass der String keine fixierte Länge hat - dass habe ich vergessen zu erwähnen, sry.
    Ich kann höchstens von rechts kommen, auf 0 prüfen und den ersten Wert ungleich 0 inkrementiere ich; wenn nicht 9, dann den folgenden.

    volkard schrieb:

    die konvertierungsfunktiobnen verstehe ich nicht, denn den 35-stelligen int würde ich als string speichern und int2string tut ja dann gar nicht sein.

    Gut, prinzipiell sollte man den String auch als ByteArray speichern können, ist jetzt aber nicht das Primäre ziel.

    EDIT: So hab ichs nun gemacht:

    function StrLen(const str: String): Cardinal; assembler;
    asm
      { str -> eax }
    
      push	edi
    
      mov		edi, eax		// address of str
    
      xor 	ecx, ecx		// zero out
      xor   al,  al			// also ...
      not   ecx					// equals -1
    
      cld         			// clear direction flag
      repne scasb       // scan bytewise and compare with al
    
      not		ecx					// not again
      dec		ecx					// don`t count 0 (of null-terminated string)
    
      mov		eax, ecx		// return result
    
      pop		edi
    end; (* of StrLen *)
    (* -------------------------------------------------------------------------- *)
    
    procedure IncNumStr(var NumStr); assembler;
    asm
    {	EAX -> NumStr }
    
    	push	esi
      push	edi
    
      {----- call StrLen -----}
      push	 eax
    
      call	 StrLen
      mov		 ecx, eax  							// result (length of string) to ecx
    
      pop		 eax
      {----- finish -----}
    
      lea		esi, [eax+ecx-1]
      xor		al, al
    
    @@repeat1:
    	cmp		al, BYTE PTR [esi]
      jne		@@Inc
      dec		esi
      jnz		@@repeat1
    
    @@Inc:
    	test	ecx, ecx
      jz		@@Exit
    
    @@repeat2:
      inc	 BYTE PTR [esi]
      cmp  BYTE PTR [esi], 58
    	je   @@1
      jmp	 @@Exit
    
    @@1:
    	mov	 BYTE PTR [esi], 48
      dec	 esi
      jmp	 @@repeat2
    
    @@Exit:
      pop		edi
      pop		esi
    end; (* of IncNumStr *)
    (* -------------------------------------------------------------------------- *)
    


  • Deswegen speichert man den String oft rückwärts, also für 4711 statt "4711" lieber "1174". Das Rechnen geht dann ein wenig schneller, aber bei der Ausgabe muß man "rückwärts vorgehen".



  • volkard schrieb:

    Deswegen speichert man den String oft rückwärts, also für 4711 statt "4711" lieber "1174". Das Rechnen geht dann ein wenig schneller, aber bei der Ausgabe muß man "rückwärts vorgehen".

    Da ich den String so in einer Datei geliefert bekomme, habe ich darauf leider keinen Einfluss. Das Problem, dass aus little big endian wird, ist dann halt vorhanden.



  • Ich weigere mich, die obige Funktion zu lesen. Editierst Du mit Notepad oder was? 🙂



  • volkard schrieb:

    while((*p--)++=='9');

    Bin ich blöd? Ich kapiere die Funktion nicht. Der Nachfolger von '9' ist ':' nicht '0'. Oder gehst du davon aus, dass abschließend noch ':' durch '0' ersetzt werden muß?



  • witte schrieb:

    volkard schrieb:

    while((*p--)++=='9');

    Bin ich blöd? Ich kapiere die Funktion nicht. Der Nachfolger von '9' ist ':' nicht '0'. Oder gehst du davon aus, dass abschließend noch ':' durch '0' ersetzt werden muß?

    Hab da wohl was vergessen.
    Vielleicht wär's eher
    while(++*p,*p=='9'+1) {*p='0';--p;++*p;}//evtl do-schleife?
    //if(*p==SENTINEL) panic();
    Keine Ahnung, weshalb dieser halbfertige Frickelcode in meine Tastatur gesprungen ist.



  • abc.w schrieb:

    Ich weigere mich, die obige Funktion zu lesen. Editierst Du mit Notepad oder was? 🙂

    Ist der Code direkt aus der Delphi IDE kopiert. Liegt daran, dass ich mit eingestelltem Tab (2 Zeichen) arbeite und manchmal eben nicht. Das Forum interpretiert ein Tab aber wohl mit 5 Zeichen.



  • FrEEzE2046 schrieb:

    Hallo Jungs,

    ich habe ein echtes Problem und zwar brauche ich Konvertierungsmöglichkeiten für eine 35-stellige (zur Basis 10) Zahl.

    Ich hoffe ihr versteht was ich meine. Hat jemand eine Idee?

    Ich komme immer ein wenig durcheinander bei 4b6f6e76657274696572756e67212121
    also von wo konvertier ich was wohin, welcher Code?
    Wie liegt die Zahl den im Speicher? (als 123456789/010203040506070809?)
    (Oder als 313233343536373839?/...)
    Und in welchen Kode soll die "Zahl konvertiert werden?
    Und wieso nicht schrittweise (also byteweise)?


Anmelden zum Antworten