#include <iostream>
#include <cmath>
#include<limits>
template<typename numeric_t>
numeric_t ln_primitive(numeric_t const &n){
numeric_t d = std::numeric_limits<numeric_t>::digits;
while(d && !(n & (1<< (--d)))){}
return d;
}
template<typename numeric_t>
constexpr numeric_t log2(numeric_t n, std::size_t approx_digits){
if(approx_digits == 0) return 0;
numeric_t _ln = 0;
std::size_t lower_digit =0;
while(approx_digits && n > std::numeric_limits<unsigned short>::max() ){
lower_digit= approx_digits >> 1;
numeric_t const upper = n>> lower_digit;
if(upper){
n = upper;
_ln += lower_digit;
approx_digits-= lower_digit;
}else{
approx_digits = lower_digit;
}
}
if(approx_digits && n) _ln += ln_primitive((unsigned short)(n));
return _ln;
}
template<typename numeric_t, std::size_t N>
constexpr numeric_t log<numeric_t, N>(numeric_t const &n){
if(N==2) return log2(n);
return log2(n) / log2(N);
}
void test(unsigned x){
std::cout << "log10("<< x <<")="<< std::log10(x) << std::endl;
std::cout << "(approx)log10("<< x <<")="<< log<unsigned,10>(x) << std::endl;
}
int main() {
test(10);
test(100);
test(1000);
test(10000);
test(100000);
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8Y21hdGg+CiNpbmNsdWRlPGxpbWl0cz4KCgoJdGVtcGxhdGU8dHlwZW5hbWUgbnVtZXJpY190PgoJbnVtZXJpY190IGxuX3ByaW1pdGl2ZShudW1lcmljX3QgY29uc3QgJm4pewoJCW51bWVyaWNfdCBkID0gc3RkOjpudW1lcmljX2xpbWl0czxudW1lcmljX3Q+OjpkaWdpdHM7CgkJd2hpbGUoZCAmJiAhKG4gJiAoMTw8ICgtLWQpKSkpe30KCQlyZXR1cm4gZDsKCX0KCgl0ZW1wbGF0ZTx0eXBlbmFtZSBudW1lcmljX3Q+Cgljb25zdGV4cHIgbnVtZXJpY190IGxvZzIobnVtZXJpY190IG4sIHN0ZDo6c2l6ZV90IGFwcHJveF9kaWdpdHMpewoJCWlmKGFwcHJveF9kaWdpdHMgPT0gMCkgcmV0dXJuIDA7CgkJbnVtZXJpY190IF9sbiA9IDA7CgkJc3RkOjpzaXplX3QgbG93ZXJfZGlnaXQgPTA7CgkJd2hpbGUoYXBwcm94X2RpZ2l0cyAmJiBuID4gc3RkOjpudW1lcmljX2xpbWl0czx1bnNpZ25lZCBzaG9ydD46Om1heCgpICl7CgkJCWxvd2VyX2RpZ2l0PSBhcHByb3hfZGlnaXRzID4+IDE7CgkJCW51bWVyaWNfdCBjb25zdCB1cHBlciA9IG4+PiBsb3dlcl9kaWdpdDsKCQkJaWYodXBwZXIpewoJCQkJbiA9IHVwcGVyOwoJCQkJX2xuICs9IGxvd2VyX2RpZ2l0OwoJCQkJYXBwcm94X2RpZ2l0cy09IGxvd2VyX2RpZ2l0OwoJCQl9ZWxzZXsKCQkJCWFwcHJveF9kaWdpdHMgPSBsb3dlcl9kaWdpdDsKCQkJfQoJCX0KCQlpZihhcHByb3hfZGlnaXRzICYmIG4pIF9sbiArPSBsbl9wcmltaXRpdmUoKHVuc2lnbmVkIHNob3J0KShuKSk7CgkJcmV0dXJuIF9sbjsKCX0KCQoJdGVtcGxhdGU8dHlwZW5hbWUgbnVtZXJpY190LCBzdGQ6OnNpemVfdCBOPgoJY29uc3RleHByIG51bWVyaWNfdCBsb2c8bnVtZXJpY190LCBOPihudW1lcmljX3QgY29uc3QgJm4pewoJCWlmKE49PTIpIHJldHVybiBsb2cyKG4pOwoJCXJldHVybiBsb2cyKG4pIC8gbG9nMihOKTsKCX0KCnZvaWQgdGVzdCh1bnNpZ25lZCB4KXsKCXN0ZDo6Y291dCA8PCAibG9nMTAoIjw8IHggPDwiKT0iPDwgc3RkOjpsb2cxMCh4KSA8PCBzdGQ6OmVuZGw7CglzdGQ6OmNvdXQgPDwgIihhcHByb3gpbG9nMTAoIjw8IHggPDwiKT0iPDwgbG9nPHVuc2lnbmVkLDEwPih4KSA8PCBzdGQ6OmVuZGw7Cn0KCmludCBtYWluKCkgewoJdGVzdCgxMCk7Cgl0ZXN0KDEwMCk7Cgl0ZXN0KDEwMDApOwoJdGVzdCgxMDAwMCk7Cgl0ZXN0KDEwMDAwMCk7CglyZXR1cm4gMDsKfQ==
prog.cpp:34:25: error: expected initializer before ‘<’ token
constexpr numeric_t log<numeric_t, N>(numeric_t const &n){
^
prog.cpp: In function ‘void test(unsigned int)’:
prog.cpp:41:49: error: expected primary-expression before ‘unsigned’
std::cout << "(approx)log10("<< x <<")="<< log<unsigned,10>(x) << std::endl;
^~~~~~~~