schnell int nach binär-string und umgekehrt konvertieren



  • hab keine ahnung obs schneller is als deins, hattes mal vor langer zeit geschrieben

    char binstr[8];
    
    void SetzeBits(unsigned char n)
    {
    	char i;
    
    	for (i=7; i >= 0 ;--i)
    	  binstr[i]=((n>>i)&1)+'0';
    }
    
    int main(void)
    {
    
    SetzeBits(8);
    
    puts(binstr);
    
    return 0;
    }
    

    das gibt dir das im little endian format aus 🙂 wenn du es in der "lesbaren" sprich big endian haben möchtest nimm folgendes, das dürfte aber langsamer sein

    void SetzeBits(unsigned char n)
    {
    	char i,r=0;
    
    	for (i=7; i >= 0 ;--i,++r)
    	  binstr[r]=((n>>i)&1)+'0';
    }
    

    bye

    tt



  • so wie ich das grad sehe is das ums doppelte langsamer als dein vorhergehender code 😉

    void inttobin2(unsigned char zahl)
    {
        binstr[7]=((zahl>>0)&1)+'0';
        binstr[6]=((zahl>>1)&1)+'0';
        binstr[5]=((zahl>>2)&1)+'0';
        binstr[4]=((zahl>>3)&1)+'0';
        binstr[3]=((zahl>>4)&1)+'0';
        binstr[2]=((zahl>>5)&1)+'0';
        binstr[1]=((zahl>>6)&1)+'0';
        binstr[0]=((zahl>>7)&1)+'0';
    }
    

    so ist er aber noch etwas schneller da er weniger operationen macht...inline und so bringt nix zumindest nicht bei mir, ach ja falls du dich wunderst ich hab binstr[8] als globalen string, kannst ja wieder reinpacken 🙂

    tschööö

    tt



  • ich konnts nich lassen und hab mal rumprobiert was mein compiler son bringt 😉 hab den lccwin32 (only c compiler) und nachdem ich die optimierungen und noch das static inline davor gepackt hab...gings mal richtig ab 😉 bei 30 Mio. Durchläufen (mein sys. xp 1700 und 256mb ram) betrug die gesamtlaufzeit des programmes irgendwas bei 590 milisek. mein profiler hat die werte schon gar nich mehr angezeigt 😉 vielleicht wär das auch noch ne option für dich 🙂 kommt sicher auf dein compiler drauf an

    static inline void inttobin2(unsigned char zahl)
    {
        binstr[7]=((zahl>>0)&1)+'0';
        binstr[6]=((zahl>>1)&1)+'0';
        binstr[5]=((zahl>>2)&1)+'0';
        binstr[4]=((zahl>>3)&1)+'0';
        binstr[3]=((zahl>>4)&1)+'0';
        binstr[2]=((zahl>>5)&1)+'0';
        binstr[1]=((zahl>>6)&1)+'0';
        binstr[0]=((zahl>>7)&1)+'0';
    }
    

    bye

    tt

    PS: was ich noch erwähnen sollte ich hab mir nur das letzte ergebnis jeweils ausgeben lassen, siehst du ja oben...sich jedes ergebnis auf dem schirm ausgeben lassen zwingt das sys ganz schön in die knie 🙂



  • static ändert nicht die geschwindigkeit.



  • frag mich nicht 🙂 "nur" mit inline gab es keine veränderung mit static schon *schulterzuck*

    bye

    tt



  • soweit so gut, wenn man die funktion "inttobin" inlined und nen constanten
    wert übergibt(z.B. <const int i=101>) dann ist sie schön schnell...
    wenn man aber nur <int i=101> (ohne const) übergibt ist die funktion zu
    langsam. nen konstanten wert übergeben bringt mir aber wenig, weil da könnte
    ich ja gleich das ergebnis ins programm reinschreiben...
    die variable global zu deklarieren hat einiges gebracht, allerdings hatte ich
    versucht das zu vermeiden,da ich ein bestehendes, nicht von mir entwickeltes
    programm optimieren soll und ich eventuellen problemen gleich aus dem weg gehen wollte.
    (vllt. ne dumme idee 🙄 )
    ach ja, die funktionen müssen das ergebnis zurrückgeben.
    in eine variable schreiben und deren inhalt dann zu nehmen ist nicht akzeptabel!
    sonst dürfte ich ein paar zig MB quellcode abändern... 😮

    hier erstmal mein aktueller code:

    //-----------------------------------------------------------------------------
    //---------------------------IntToBin------------------------------------------
    
    static char binstr2[9]={NULL};
    static inline char* inttobin2(unsigned char zahl)
    {
        binstr2[7]=(zahl&1)+48;
        binstr2[6]=((zahl>>1)&1)+48;
        binstr2[5]=((zahl>>2)&1)+48;
        binstr2[4]=((zahl>>3)&1)+48;
        binstr2[3]=((zahl>>4)&1)+48;
        binstr2[2]=((zahl>>5)&1)+48;
        binstr2[1]=((zahl>>6)&1)+48;
        binstr2[0]=((zahl>>7)&1)+48;
        return binstr2;
    }
    
    //-----------------------------------------------------------------------------
    //---------------------------BinToInt------------------------------------------
    
    static inline unsigned int bintoint(char *binstr)
    {
      return ((binstr[0]&1)<<7)+
             ((binstr[1]&1)<<6)+
             ((binstr[2]&1)<<5)+
             ((binstr[3]&1)<<4)+
             ((binstr[4]&1)<<3)+
             ((binstr[5]&1)<<2)+
             ((binstr[6]&1)<<1)+
             ((binstr[7]&1));
    }
    

    hoffe ihr habt noch n paar ideen, die mich auf den schnellsten weg bringen 😉

    mfg
    Alex



  • oke...also mir kam da was in denn sinn

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    int binstr[8];
    
    typedef struct _binchar
    {
    	unsigned _0:1;
    	unsigned _1:1;
    	unsigned _2:1;
    	unsigned _3:1;
    	unsigned _4:1;
    	unsigned _5:1;
    	unsigned _6:1;
    	unsigned _7:1;
    
    }binchar;
    
    typedef union _blubb
    {
    	binchar zahl_bin;
    	unsigned char input;
    
    }blubb;
    
    void inttobin3(unsigned char zahl)
    {
        static blubb test_input;
        test_input.input = zahl;
    
        binstr[7]=test_input.zahl_bin._0;
        binstr[6]=test_input.zahl_bin._1;
        binstr[5]=test_input.zahl_bin._2;
        binstr[4]=test_input.zahl_bin._3;
        binstr[3]=test_input.zahl_bin._4;
        binstr[2]=test_input.zahl_bin._5;
        binstr[1]=test_input.zahl_bin._6;
        binstr[0]=test_input.zahl_bin._7;
    }
    
    int main(void)
    {
        int ctr;
    
        inttobin3(8);
    
        for(ctr = 0; ctr < 8; ++ctr)
    	printf("%d", binstr[ctr]);
    return 0;
    }
    

    wenn ich das aufrufe 😉 ein paar mal...dann wird laut profiler eigentlich nur noch zeit in main() verbraucht 😉

    das einzige was nicht mehr wirklich geht ist das als char array zu speichern und auszugeben weil 1 und 0 dezimal im ascii satz was anderes sind... deswegen ist bei mir binchar nun halt mal ein int geworden 🙂 du kannst aber als alternativ möglichkeit das trotzdem in nem char array speichern das dann wenn die ausgabe benötigt wird nach 0 und 1 durchparsen und durch 48 und 49 ersetzen (sollten doch die "richtigen" zahlen codes sein oder?)

    bye

    tt

    PS: sorry für die z.t. blöden namen 😉



  • Also wenn du es richtig schnell haben willst, dann nimm halt ein array anstelle einer Funktion.

    const char inttobin[256][9]={
        "00000000",
        "00000001",
        "00000010",
        "00000011",
        "00000100",
        ...
        "11111111"
    };
    
    int main() {
        const char *bin;
    
        bin=inttobin[3];
    
        return 0;
    }
    


  • hab meinen rechner zerschossen (man sollte besser assembler können,bevor man versucht damit hardwaregeräte anzusprechen)
    , deshalb kann ichs im mom nicht testen,
    aber das mit dem array scheint mir eine sehr gute idee...
    werds testen sobald meine kiste wieder funzt...

    mfg
    Alex



  • Eine Frage an den ursprünglichen Fragesteller (AlexC++):
    Hast du mit einem Profiler festgestellt, dass diese Funktion der Flaschenhals ist oder vermutest du das nur?


Anmelden zum Antworten