Integer in String aber "manuell"
-
ich brauch eine effizizente lösung um einen integer in ein char array ala string zu bekommen, aber mir steht dabei leider keine sinnvolle bibliothek zur verfügung!
int myInteger; int temp; char myText[6]; temp = myInteger; myText[0] = temp%10000; temp/=10000; myText[1] = temp%1000; temp/=1000; myText[2] = temp%100; temp/=100; myText[3] = temp%10; temp/=10; myText[4] = temp; myText[5] = 0;
das problem an dieser stelle ist das modulo weil es zu langsam ist, hat jemand was effizienteres? ich find immer nur die stl umwandlungen ...
-
Ceos schrieb:
das problem an dieser stelle ist das modulo weil es zu langsam ist, hat jemand was effizienteres? ich find immer nur die stl umwandlungen ...
Warum ist das zu langsam? Vllt. hilft es, wenn du von Hinten anfängst und in einer Schleife immer modulo durch 10 teilst.
-
Ehrlich gesagt habe ich nicht genau verstanden, wie der Integer in den String umgewandelt werden soll!
Falls du die einzelnen Bytes ansprechen willst dann kannst du das über
unions:BSP:
#include <stdio.h> union UNION { int Int; char Char[sizeof(int)]; }; int main() { UNION myunion; myunion.Int = 0x11223344; //für 32 Bit systeme //für 32 Bit systeme printf("%x\n", (int)myunion.Char[0] ); //unter Windows 0x44 printf("%x\n", (int)myunion.Char[1] ); //unter Windows 0x33 printf("%x\n", (int)myunion.Char[2] ); //unter Windows 0x22 printf("%x\n", (int)myunion.Char[3] ); //unter Windows 0x11 return 0; }
zu unions http://www.imb-jena.de/~gmueller/kurse/c_c++/c_union.html
//hab ich mir gar nicht durch gelesen nur gegoogelt
Kleines Problem hast du(darf ich du schreiben?) natürlich da das auf Windows(oder allgemein x86??? [-->ich weiß es nicht]) als Little-Endian abgelegt wird.
http://de.wikipedia.org/wiki/Byte-ReihenfolgeAlso wäre deine obige Version zwar langsamer aber plattformunabhängig!
Ich hoffe du hast auch das gemeint!
-
Ceos schrieb:
ich brauch eine effizizente lösung um einen integer in ein char array ala string zu bekommen, aber mir steht dabei leider keine sinnvolle bibliothek zur verfügung!
gleich als string einlesen und feddich
-
au haua aua schrieb:
Ceos schrieb:
ich brauch eine effizizente lösung um einen integer in ein char array ala string zu bekommen, aber mir steht dabei leider keine sinnvolle bibliothek zur verfügung!
gleich als string einlesen und feddich
Zeig mal! (Integer in String aber "manuell")
-
such mal im internet nach 'hackers delight division by constants'. es gibt's tricks, wie man divison und modulus mit shifts und additionen hinbekommt. geht zwar nicht mit jedem divisor, aber mit 5 und 10 auf jeden fall. damit kannst du die / und % loswerden, was eventuell schneller sein kann.
-
; void int_to_str( char *dst, int src ) { sub esp,0Ch ; size_t i = log10( src ) + 1; fld qword ptr [__real@40c81c8000000000 (862100h)] push ebx push esi mov ebx,3039h call _CIlog10 (861880h) fadd qword ptr [__real@3ff0000000000000 (8620F8h)] fnstcw word ptr [esp+0Ah] movzx eax,word ptr [esp+0Ah] or eax,0C00h mov dword ptr [esp+0Ch],eax fldcw word ptr [esp+0Ch] fistp qword ptr [esp+0Ch] mov eax,dword ptr [esp+0Ch] ; dst[ i-- ] = '\0'; mov byte ptr [eax+3039h],0 dec eax fldcw word ptr [esp+0Ah] ; for( ; src; src /= 10, --i ) { ; dst[ i ] = '0' + ( src % 10 ); lea esi,[eax+3039h] jmp int_to_str+50h (861050h) lea ecx,[ecx] mov eax,66666667h imul ebx sar edx,2 mov ecx,edx shr ecx,1Fh add ecx,edx mov al,cl mov dl,0Ah imul dl sub bl,al add bl,30h mov byte ptr [esi],bl mov ebx,ecx dec esi test ebx,ebx jne int_to_str+50h (861050h) ; } pop esi pop ebx ; }
Hilf mir mal kurz, ich seh' hier keine Division...
#include <stdlib.h> #include <time.h> #include <stdio.h> #include <math.h> #include <intrin.h> #define MAX_NUMBERS 100000 void int_to_str_sprintf( char *dst, int src ) { sprintf( dst, "%i", src ); } void int_to_str_log( char *dst, int src ) { size_t i = ( size_t ) log10( src ) + 1; dst[ 0 ] = '0'; dst[ i-- ] = '\0'; for( ; src; src /= 10, --i ) { dst[ i ] = '0' + ( src % 10 ); } } void int_to_str_loop( char *dst, int src ) { size_t i = 1; int tmp = src; for( ; tmp; tmp /= 10, ++i ); dst[ 0 ] = '0'; dst[ i-- ] = '\0'; for( ; src; src /= 10, --i ) { dst[ i ] = '0' + ( src % 10 ); } } int main( void ) { int number[ MAX_NUMBERS ]; char string[ 10 ]; unsigned __int64 start, stop; size_t i = 0; srand( ( unsigned int ) time( 0 ) ); for( ; i < MAX_NUMBERS; number[ i++ ] = rand( ) ); start = __rdtsc( ); for( i = 0; i < MAX_NUMBERS; ++i ) { int_to_str_sprintf( string, number[ i ] ); } stop = __rdtsc( ); printf( "sprintf: %8u\n", ( stop - start ) / MAX_NUMBERS ); start = __rdtsc( ); for( i = 0; i < MAX_NUMBERS; ++i ) { int_to_str_log( string, number[ i ] ); } stop = __rdtsc( ); printf( "log: %8u\n", ( stop - start ) / MAX_NUMBERS ); start = __rdtsc( ); for( i = 0; i < MAX_NUMBERS; ++i ) { int_to_str_loop( string, number[ i ] ); } stop = __rdtsc( ); printf( "loop: %8u\n", ( stop - start ) / MAX_NUMBERS ); }
Ausgabe:
sprintf: 775 log: 167 loop: 97
Mit 'nem lookup table gehts wahrscheinlich noch schneller... Wofür?
cheers, Swordfish
PS: Aja, Intel Merom Stepping M0, 32kB/32kB L1, 2MB L2
-
Swordfish schrieb:
Hilf mir mal kurz, ich seh' hier keine Division...
das zeichen / heisst 'dividieren' und das % heisst 'dividiere und gib mir den rest'. beides kann sehr lahm sein wobei letzteres das schlimmere von beiden ist.
-
foobar fread schrieb:
das zeichen / heisst 'dividieren' und das % heisst 'dividiere und gib mir den rest'.
Na gell, wirklich? Dann verrat' ich Dir auch mal ne "Neuigkeit": Diese Art von Zeichen heißen Operatoren...
Du gehst mir schön langsam richtig auf den Keks: Wo siehst du im vom Compiler erzeugten Maschinencode ein
div
? Wozu denkst du, mach ich mir die Mühe, das Assembly zu posten!?
-
Swordfish schrieb:
Wozu denkst du, mach ich mir die Mühe, das Assembly zu posten!?
na, weil du bestimmt ganz genau weisst, dass der OP ein X86 derivat und den gleichen compiler benutzt wie du. mit dem asm-code ist ihm wirklich sehr geholfen.
-
Swordfish schrieb:
Hilf mir mal kurz, ich seh' hier keine Division...
... sar edx,2 ...
:p
-
x86-freak schrieb:
na, weil du bestimmt ganz genau weisst, dass der OP ein X86 derivat und den gleichen compiler benutzt wie du. mit dem asm-code ist ihm wirklich sehr geholfen.
Nein, um zu zeigen, dass heutige Compiler schlau genug sind, selbst zu optimieren und deinen Bitshift-Vorschlag als das zu entlarven, was er ist: Unnötig.
Gut - eine Division hab' ich tatsächlich übersehen. Poste Du doch mal Deine "Traumvorstellung" einer solchen Funktion, freaky.
cheers, Swordfish
-
Swordfish schrieb:
Nein, um zu zeigen, dass heutige Compiler schlau genug sind, selbst zu optimieren...
schlau ist relativ. und die möglichkeiten eines vc++ auf x86 könnte sein compiler auf seiner maschine eben nicht haben, z.b. für division und modulo subroutinen aufrufen usw, die architekturbedingt relativ aufwendige berechnungen machen.