如何在c/c ++中编写日志库(2)

rus*_*ell 90 c c++

有没有办法写log(base 2)函数?

C语言有2个内置函数 - >>

1. log基础e.

2. log10基数10;

但我需要基数2的日志功能.如何计算这个.

Ada*_*ume 185

简单的数学:

    log 2(x)= log y(x)/ log y(2)

其中y可以是任何东西,标准日志函数是10或e.

  • 很多.我得到了答案. (4认同)

Mat*_*hen 52

C99拥有log2(以及log2flog2l浮法和长双).

  • 这应该是最佳答案。 (2认同)

tom*_*gic 51

如果您正在寻找积分结果,您可以确定值中设置的最高位并返回其位置.

  • ...或`while(i >> = 1){++ l; }` (36认同)
  • 还有一个很好的bit-twiddling方法(取自Java的`Integer.highestOneBit(int)`方法):`i | =(i >> 1); i | =(i >> 2); i | =(i >> 4); i | =(i >> 8); i | =(i >> 16); 返回i - (i >>> 1);` (26认同)
  • @Joey那会假设整数是32位宽,不是吗?对于64位,它将有一个额外的"i >> 32".但由于Java只有32位整数,所以很好.对于C/C++,需要考虑它. (2认同)

log*_*ray 40

#define M_LOG2E 1.44269504088896340736 // log2(e)

inline long double log2(const long double x){
    return log(x) * M_LOG2E;
}
Run Code Online (Sandbox Code Playgroud)

(乘法可能快于除法)

  • 只是想澄清 - 使用日志转换规则 + log_2(e) = 1/log_e(2) --> 我们得到结果 (2认同)

小智 13

log2(int n) = 31 - __builtin_clz(n)
Run Code Online (Sandbox Code Playgroud)


Pat*_*ick 9

http://en.wikipedia.org/wiki/Logarithm所述:

logb(x) = logk(x) / logk(b)
Run Code Online (Sandbox Code Playgroud)

意思就是:

log2(x) = log10(x) / log10(2)
Run Code Online (Sandbox Code Playgroud)

  • 请注意,您可以预先计算log10(2)以提高性能. (11认同)
  • @abelenky:由于`log10()`是C标准中定义的函数,编译器可以"特别"对其进行处理,包括预先计算结果,我认为是@Johannes的建议? (3认同)

bka*_*sbk 8

如果你想快速,你可以使用像Bit Twiddling Hacks一样的查找表(仅限整数log2).

uint32_t v; // find the log base 2 of 32-bit v
int r;      // result goes here

static const int MultiplyDeBruijnBitPosition[32] = 
{
  0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30,
  8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31
};

v |= v >> 1; // first round down to one less than a power of 2 
v |= v >> 2;
v |= v >> 4;
v |= v >> 8;
v |= v >> 16;

r = MultiplyDeBruijnBitPosition[(uint32_t)(v * 0x07C4ACDDU) >> 27];
Run Code Online (Sandbox Code Playgroud)

此外,你应该看看你的编译器内置的方法,如_BitScanReverse可能会更快,因为它可以在硬件完全计算.

请参阅可能的重复如何在C++中执行整数log2()?


Ust*_*gat 5

uint16_t log2(uint32_t n) {//but truncated
     if (n==0) throw ...
     uint16_t logValue = -1;
     while (n) {//
         logValue++;
         n >>= 1;
     }
     return logValue;
 }
Run Code Online (Sandbox Code Playgroud)

和tomlogic的基本一样。