Laenge bzw. Anzahl Stellen von integer-Wert ermitteln



  • Hallo zusammen

    Ich habe eine Frage bezueglich integer-Werten. Gibt es eine Methode, welche die Laenge eines solchen integerwertes ermitteln kann, sowas wie strlen() einfach fuer integer?

    Danke im Voraus und Gruss
    Fabian



  • FabianR schrieb:

    Hallo zusammen

    Ich habe eine Frage bezueglich integer-Werten. Gibt es eine Methode, welche die Laenge eines solchen integerwertes ermitteln kann, sowas wie strlen() einfach fuer integer?

    Danke im Voraus und Gruss
    Fabian

    sizeof() liefert die Länge eines Integers auf deinem System. Das dürfte zwischen 2 und 8 liegen. Ist aber konstant. Ich denke du meinst die Stellenanzahl im dezimal System. Die könntest du mit dem Logarithmus berechnen.

    Gruß
    Don06



  • strlen(itoa(meinInt));
    

    Ist aber C und nicht performant. 😉



  • Fellhuhn schrieb:

    strlen(itoa(meinInt));
    

    Ist aber C und nicht performant. 😉

    itoa ist nichtmal C :p



  • Naj vllt. mal in Mathe aufgepasst und du wüsstest, das es da einen einfachen Trick mit dem 10er Logarithmus gibt ...



  • Würde ich mal ganz spontan so machen, und nicht mit log10!

    template <typename T>
    unsigned count_digits(T num, unsigned base = 10) {
        unsigned count = 0;
        do ++count while(num /= base);
        return count;
    }
    


  • Entenwickler schrieb:

    do ++count; /* <- */ while(num /= base);
    

    greetz, Swordfish



  • idee ok, template nicht. geht nur für integer auf die weise.



  • hi-ho,

    ...das wäre noch ne möglichkeit:

    int x=123456, z=1, n=10; //n ist die maximal zu erwartende Anzahl Dezimalstellen
    bool Exit;
    
    for(int j=1; j<n; j++)
    {
       z*=10;
    }
    
    while(!Exit)
    {
       if((((double)x)/z)<1)
       {
           z/=10;
           n--;
       }
       else
       {
           cout<<"Die Zahl in Variable x hat "<<n<<" Dezimalstellen."<<endl;
           Exit=true;
       }
    }
    


  • nimm den logaithmus, kapp die Nachkommstellen ab und zähl eins dazu



  • Hab mal interessehalber die Geschwindigkeiten von den jeweiligen Methoden getestet.

    inline unsigned countdigits(int x)
    {
      static char tmp[20];
      return strlen(itoa(x,tmp,10));
    }
    

    11.8 sec

    inline unsigned countdigits(int x)
    {
      return static_cast<unsigned>(log10(x))+1;
    }
    

    11.4 sec

    inline unsigned countdigits(int x)
    {
      unsigned count=0;
      do ++count; while(x/=10);
      return count;
    }
    

    2.45 sec

    bei folgender Schleife:

    int y=0;
    for (int i=0;i<10000000;i++)
    {
      y+=countdigits(i+1);
      y+=countdigits(i+2);
      y+=countdigits(i+3);
      y+=countdigits(i+4);
      y+=countdigits(i+5);
    }
    


  • inline unsigned countdigits(int x)
    {
      unsigned count=0;
      do ++count; while(x/=10);
      return count;
    }
    

    2.45 sec

    mach doch andersrum, musste nich' dividieren:

    inline unsigned int countdigits(unsigned int x)
    {
    	unsigned count=1;
    	unsigned int value= 10;
    	while (x>=value)
    	{
    		value*=10;
    		count++;
    	}
    	return count;
    }
    

    (bei bedarf einen spezialfall fuer x>(1<<32)/10 ergaenzen)



  • hellihjb schrieb:

    mach doch andersrum, musste nich' dividieren:

    Stimmt, deine Variante ist mit 0.65 sec noch einmal deutlich schneller 👍



  • int log2 (int v)
    {
        static const int MultiplyDeBruijnBitPosition[32] = 
        {
              0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8, 
                31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9
        };
    
        v |= v >> 1; // first round down to power of 2 
        v |= v >> 2;
        v |= v >> 4;
        v |= v >> 8;
        v |= v >> 16;
        v = (v >> 1) + 1;
    
        return MultiplyDeBruijnBitPosition[(v * 0x077CB531UL) >> 27];
    }
    
    int log10 (int v)
    {
        static double log_2_10 = std::log(2) / std::log(10);
    
        return int(log_2_10 * log2(v));
    }
    

    log2 ist von hier geklaut 😉

    /edit: Sieh an, da gibts auch noch was double-freies für log10:

    int log10 (int v)
    {
        static unsigned int const PowersOf10[] = 
            {1, 10, 100, 1000, 10000, 100000,
             1000000, 10000000, 100000000, 1000000000};
    
        t = (log2(v) + 1) * 1233 >> 12; // (use a lg2 method from above)
        return t - (v < PowersOf10[t]);
    }
    


  • Ist ganz interessant, aber da diese log2-Variante nur Ganzzahlen als Rückgabewert liefert, eignet sie sich hier nicht so gut. So gesteht sie beispielsweise erst 2^14 (16384) die verdienten fünf Dezimalstellen zu.



  • FabianR schrieb:

    Hallo zusammen

    Ich habe eine Frage bezueglich integer-Werten. Gibt es eine Methode, welche die Laenge eines solchen integerwertes ermitteln kann, sowas wie strlen() einfach fuer integer?

    Danke im Voraus und Gruss
    Fabian

    ganz simpel:

    int a,i,j=0;
    scanf("%i",&i); // deine zahl eingeben
    for(a=1;a<i;a*=10) //schleife für die stellen
    {
    j++; // die stellen
    }
    printf("Deine Zahl %i hat %i Stellen",i,j);

    // voila frohe weihnachten :xmas1:


  • Mod

    Wenn schon mit Arrays angefangen wird, darf ein Suchalgorithmus nicht fehlen

    unsigned countdigits(unsigned x)
    {
        static const unsigned foo[] =
        {
              10u, 100u, 1000u,
              10u * 1000u, 100u * 1000u, 1000u * 1000u,
              10u * 1000u * 1000u, 100u * 1000u * 1000u, 1000u * 1000u * 1000u
        };
        return static_cast< unsigned >( std::upper_bound( foo, foo + sizeof foo / sizeof *foo, x ) - foo + 1 );
    }
    


  • FabianR schrieb:

    Hallo zusammen

    Ich habe eine Frage bezueglich integer-Werten. Gibt es eine Methode, welche die Laenge eines solchen integerwertes ermitteln kann, sowas wie strlen() einfach fuer integer?

    Danke im Voraus und Gruss
    Fabian

    ich weiss is zwei jahre her aber was solls
    in C
    ist ganz simpel:

    #include <stdio.h>
    #include <stdlib.h>
    
    int main(int argc,char*argv[])
    {
        int a,i,j=0;
        scanf("%i",&i);                                  // deine zahl eingeben
        for(a=1;a<i;a*=10)                               // schleife für die stellen
        {
            j++;                                         // die stellen
        }
        printf("Deine Zahl %i hat %i Stellen",i,j);      // voila und frohe weihnachten
        getch();
        return 0;                                        // ps ick hasse weihnachten
    }
    

  • Mod

    @hacktic: Kauf dir mal einen Kalender


Anmelden zum Antworten