如何在 c/c++ 中编写 log base(2)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3064926/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to write log base(2) in c/c++
提问by russell
Is there any way to write log(base 2) function?
有没有办法编写 log(base 2) 函数?
The C language has 2 built in function -->>
C语言有2个内置函数-->>
1.log
which is base e.
1.log
以 e 为基数。
2.log10
base 10;
2.log10
基数 10;
But I need log function of base 2.How to calculate this.
但我需要基数为 2 的对数函数。如何计算。
回答by Adam Crume
Simple math:
简单的数学:
????log2(x) = logy(x) / logy(2)
????log 2( x) = log y( x) / log y(2)
where ycan be anything, which for standard log functions is either 10 or e.
其中y可以是任何东西,对于标准日志函数,它是 10 或e。
回答by Matthew Flaschen
回答by tomlogic
If you're looking for an integral result, you can just determine the highest bit set in the value and return its position.
如果您正在寻找整数结果,您只需确定值中设置的最高位并返回其位置。
回答by logicray
#define M_LOG2E 1.44269504088896340736 // log2(e)
inline long double log2(const long double x){
return log(x) * M_LOG2E;
}
(multiplication may be faster than division)
(乘法可能比除法快)
回答by w00t
log2(int n) = 31 - __builtin_clz(n)
回答by Patrick
As stated on http://en.wikipedia.org/wiki/Logarithm:
如http://en.wikipedia.org/wiki/Logarithm 所述:
logb(x) = logk(x) / logk(b)
Which means that:
意思就是:
log2(x) = log10(x) / log10(2)
回答by bkausbk
If you want to make it fast, you could use a lookup table like in Bit Twiddling Hacks(integer log2 only).
如果你想让它更快,你可以使用像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];
In addition you should take a look at your compilers builtin methods like _BitScanReverse
which couldbe faster because it may entirely computed in hardware.
此外,您应该查看编译器的内置方法,例如_BitScanReverse
哪些可能更快,因为它可能完全在硬件中计算。
Take also a look at possible duplicate How to do an integer log2() in C++?
也看看可能的重复如何在 C++ 中做一个整数 log2()?
回答by Ustaman Sangat
回答by the_void
log2(x) = log10(x) / log10(2)
回答by David Reinagel
I needed to have more precision that just the position of the most significant bit, and the microcontroller I was using had no math library. I found that just using a linear approximation between 2^n values for positive integer value arguments worked well. Here is the code:
我需要更高的精度,仅是最重要位的位置,而我使用的微控制器没有数学库。我发现对于正整数值参数仅使用 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));
}
In my main program, I needed to calculate N * log2(N) / 2 with an integer result:
在我的主程序中,我需要用整数结果计算 N * log2(N) / 2:
temp = (((uint32_t) N) * approx_log_base_2_N_times_256) / 512;
温度 = (((uint32_t) N) * approx_log_base_2_N_times_256) / 512;
and all 16 bit values were never off by more than 2%
并且所有 16 位值的偏差从未超过 2%