如何用c / c ++写日志库(2)

有没有办法写日志(基2)的function?

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

1.基本的log

2. log10 base 10;

但是我需要base 2的日志function。如何计算这个。

简单的math:

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

其中y可以是任何东西,对于标准日志function是10或者e

如果你正在寻找一个完整的结果,你可以确定在该值设置的最高位,并返回其位置。

 #define M_LOG2E 1.44269504088896340736 // log2(e) inline long double log2(const long double x){ return log(x) * M_LOG2E; } 

(乘法可能快于除法)

C99有log2 (以及log2flog2l用于float和long double)。

正如http://en.wikipedia.org/wiki/Logarithm所述; :

 logb(x) = logk(x) / logk(b) 

意思就是:

 log2(x) = log10(x) / log10(2) 
 log2(int n) = 31 - __builtin_clz(n) 

如果你想让速度更快,你可以使用类似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]; 

另外,你应该看看像_BitScanReverse这样的编译器内build方法,它可以更快,因为它可能完全用硬件计算。

也看看可能的重复如何做一个整数log2()在C + +?

 log2(x) = log10(x) / log10(2) 

你必须包括math.h(C)或cmath(C ++)当然要记住,你必须遵循我们知道的math…只有数字> 0。

例:

 #include <iostream> #include <cmath> using namespace std; int main(){ cout<<log2(number); } 
 uint16_t log2(uint32_t n) {//but truncated if (n==0) throw ... uint16_t logValue = -1; while (n) {// logValue++; n >>= 1; } return logValue; } 

基本上和tomlogic的一样。

我需要更精确的位置才是最重要的,而我使用的微控制器没有math库。 我发现只使用2 ^ n值之间的正整数值参数的线性近似效果很好。 这里是代码:

 uint16_t approx_log_base_2_N_times_256(uint16_t n) { uint16_t msb_only = 0x8000; uint16_t exp = 15; if (n == 0) return (-1); while ((n & msb_only) == 0) { msb_only >>= 1; exp--; } return (((uint16_t)((((uint32_t) (n ^ msb_only)) << 8) / msb_only)) | (exp << 8)); } 

在我的主程序中,我需要用一个整数结果来计算N * log2(N)/ 2:

temp(((uint32_t)N)* approx_log_base_2_N_times_256)/ 512;

并且所有的16位值都不会超过2%

咨询你的基础math课程, log n / log 2 。 在这种情况下,selectlog还是log10并不重要,除以新的base的log就行。