fork(1) download
  1. #include <iostream>
  2. #include <cmath>
  3. #include<limits>
  4.  
  5.  
  6. template<typename numeric_t>
  7. numeric_t ln_primitive(numeric_t const &n){
  8. numeric_t d = std::numeric_limits<numeric_t>::digits;
  9. while(d && !(n & (1<< (--d)))){}
  10. return d;
  11. }
  12.  
  13. template<typename numeric_t>
  14. constexpr numeric_t log2(numeric_t n, std::size_t approx_digits){
  15. if(approx_digits == 0) return 0;
  16. numeric_t _ln = 0;
  17. std::size_t lower_digit =0;
  18. while(approx_digits && n > std::numeric_limits<unsigned short>::max() ){
  19. lower_digit= approx_digits >> 1;
  20. numeric_t const upper = n>> lower_digit;
  21. if(upper){
  22. n = upper;
  23. _ln += lower_digit;
  24. approx_digits-= lower_digit;
  25. }else{
  26. approx_digits = lower_digit;
  27. }
  28. }
  29. if(approx_digits && n) _ln += ln_primitive((unsigned short)(n));
  30. return _ln;
  31. }
  32.  
  33. template<typename numeric_t, std::size_t N>
  34. constexpr numeric_t log(numeric_t const &n){
  35. if(N==2) return log2(n);
  36. return log2(n) / log2(N);
  37. }
  38.  
  39. void test(unsigned x){
  40. std::cout << "log10("<< x <<")="<< std::log10(x) << std::endl;
  41. std::cout << "(approx)log10("<< x <<")="<< log<unsigned,10>(x) << std::endl;
  42. }
  43.  
  44. int main() {
  45. test(10);
  46. test(100);
  47. test(1000);
  48. test(10000);
  49. test(100000);
  50. return 0;
  51. }
Success #stdin #stdout 0s 16056KB
stdin
Standard input is empty
stdout
log10(10)=1
(approx)log10(10)=1
log10(100)=2
(approx)log10(100)=2
log10(1000)=3
(approx)log10(1000)=3
log10(10000)=4
(approx)log10(10000)=4
log10(100000)=5
(approx)log10(100000)=5