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)?