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
Based on Mats Petersson approach, but compile time generation of cache.
#include
#include
#include
// digits
template
constexpr T digits(T number) {
return number == 0 ? 0
: 1 + digits(number / 10);
}
// pow
// https://stackoverflow.com/questions/24656212/why-does-gcc-complain-error-type-intt-of-template-argument-0-depends-on-a
// unfortunatly we can't write `template ` because of partial specialization `PowerOfTen`
template
struct PowerOfTen {
enum { value = 10 * PowerOfTen::value };
};
template
struct PowerOfTen {
enum { value = 1 };
};
// sequence
template
struct pow10_sequence { };
template
struct make_pow10_sequence_from
: make_pow10_sequence_from {
//
};
template
struct make_pow10_sequence_from
: pow10_sequence {
//
};
// base10list
template
constexpr std::array base10list(pow10_sequence) {
return {{ PowerOfTen::value... }};
}
template
constexpr std::array base10list() {
return base10list(make_pow10_sequence_from());
}
template
constexpr std::array::max())> base10list() {
return base10list::max())>();
};
// main pow function
template
static T template_quick_pow10(T n) {
static auto values = base10list();
return values[n];
}
// client code
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] == 't') {
for(long i = 0; i < outer_loops / n; i++) {
for(int j = 1; j < n+1; j++) {
sum += template_quick_pow10(n);
}
}
}
std::cout << "sum=" << sum << std::endl;
return 0;
}
Code does not contain quick_pow10, integer_pow, opt_int_pow for better readability, but tests done with them in the code.
Compiled with gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5), using -Wall -O2 -std=c++0x, gives the following results:
$ g++ -Wall -O2 -std=c++0x main.cpp
$ time ./a.out 8 a
sum=100000000000000000
real 0m0.438s
user 0m0.432s
sys 0m0.008s
$ time ./a.out 8 b
sum=100000000000000000
real 0m8.783s
user 0m8.777s
sys 0m0.004s
$ time ./a.out 8 c
sum=100000000000000000
real 0m6.708s
user 0m6.700s
sys 0m0.004s
$ time ./a.out 8 t
sum=100000000000000000
real 0m0.439s
user 0m0.436s
sys 0m0.000s