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-Reihenfolge

    Also 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.
    🙂


Log in to reply