Any way faster than pow() to compute an integer power of 10 in C++?

后端 未结 12 892
逝去的感伤
逝去的感伤 2020-12-05 13:25

I know power of 2 can be implemented using << operator. What about power of 10? Like 10^5? Is there any way faster than pow(10,5) in C++? It is a pretty straight-forw

12条回答
  •  日久生厌
    2020-12-05 13:46

    Something like this:

    int quick_pow10(int n)
    {
        static int pow10[10] = {
            1, 10, 100, 1000, 10000, 
            100000, 1000000, 10000000, 100000000, 1000000000
        };
    
        return pow10[n]; 
    }
    

    Obviously, can do the same thing for long long.

    This should be several times faster than any competing method. However, it is quite limited if you have lots of bases (although the number of values goes down quite dramatically with larger bases), so if there isn't a huge number of combinations, it's still doable.

    As a comparison:

    #include 
    #include 
    #include 
    
    static int quick_pow10(int n)
    {
        static int pow10[10] = {
            1, 10, 100, 1000, 10000, 
            100000, 1000000, 10000000, 100000000, 1000000000
        };
    
        return pow10[n]; 
    }
    
    static int integer_pow(int x, int n)
    {
        int r = 1;
        while (n--)
           r *= x;
    
        return r; 
    }
    
    static int opt_int_pow(int n)
    {
        int r = 1;
        const int x = 10;
        while (n)
        {
            if (n & 1) 
            {
               r *= x;
               n--;
            }
            else
            {
                r *= x * x;
                n -= 2;
            }
        }
    
        return r; 
    }
    
    
    int main(int argc, char **argv)
    {
        long long sum = 0;
        int n = strtol(argv[1], 0, 0);
        const long outer_loops = 1000000000;
    
        if (argv[2][0] == 'a')
        {
            for(long i = 0; i < outer_loops / n; i++)
            {
                for(int j = 1; j < n+1; j++)
                {
                    sum += quick_pow10(n);
                }
            }
        }
        if (argv[2][0] == 'b')
        {
            for(long i = 0; i < outer_loops / n; i++)
            {
                for(int j = 1; j < n+1; j++)
                {
                    sum += integer_pow(10,n);
                }
            }
        }
    
        if (argv[2][0] == 'c')
        {
            for(long i = 0; i < outer_loops / n; i++)
            {
                for(int j = 1; j < n+1; j++)
                {
                    sum += opt_int_pow(n);
                }
            }
        }
    
        std::cout << "sum=" << sum << std::endl;
        return 0;
    }
    

    Compiled with g++ 4.6.3, using -Wall -O2 -std=c++0x, gives the following results:

    $ g++ -Wall -O2 -std=c++0x pow.cpp
    $ time ./a.out 8 a
    sum=100000000000000000
    
    real    0m0.124s
    user    0m0.119s
    sys 0m0.004s
    $ time ./a.out 8 b
    sum=100000000000000000
    
    real    0m7.502s
    user    0m7.482s
    sys 0m0.003s
    
    $ time ./a.out 8 c
    sum=100000000000000000
    
    real    0m6.098s
    user    0m6.077s
    sys 0m0.002s
    

    (I did have an option for using pow as well, but it took 1m22.56s when I first tried it, so I removed it when I decided to have optimised loop variant)

提交回复
热议问题