#include #include #include #include using namespace std; unsigned long long rdtsc (void) { unsigned int low, high; asm volatile ("rdtsc": "=a"(low), "=d"(high)); return (static_cast(high) << 32) | low; } unsigned long long simple_power10(unsigned long long i) { unsigned long long current = 10000000000000000000ULL; while (true) { if (current <= i) return current + !current; current /= 10; } } template struct p10 { const static T value = T(10) * p10::value; }; template struct p10 { const static T value = T(1); }; template struct compare10 { static T compare(const T x) { if (x >= p10::value) return compare10::compare(x); else return compare10::compare(x); } }; template struct compare10 { static T compare(const T x) { return p10::value; } }; template T template_power10(T x) { return compare10::digits10>::compare(x); } double old_random(void) { return static_cast(rand()) / RAND_MAX; } template T generic_random(R callback) { return static_cast(callback(old_random()) * numeric_limits::max()); } double identity(double x) { return x; } template unsigned long long test(T callback) { unsigned long long start = rdtsc(); for (int i = 0; i < 1000000; i++) callback(generic_random(ptr_fun(identity))); return rdtsc() - start; } int main(void) { printf ("naive, uniform %lld\n", test(ptr_fun(simple_power10))); printf ("template, uniform %lld\n", test(ptr_fun(template_power10))); return 0; }