有没有办法编写以2为底的对数函数 log(base 2)?
C语言中有两个内置函数 -->
1. log
是以自然数e为底。
2. log10
是以10为底。
但我需要以2为底的log函数。如何计算呢?
有没有办法编写以2为底的对数函数 log(base 2)?
C语言中有两个内置函数 -->
1. log
是以自然数e为底。
2. log10
是以10为底。
但我需要以2为底的log函数。如何计算呢?
简单数学:
log2 (x) = logy (x) / logy (2)
其中 y 可以是任何值,在标准对数函数中通常为 10 或 e。
Integer.highestOneBit(int)
方法):i |= (i >> 1); i |= (i >> 2); i |= (i >> 4); i |= (i >> 8); i |= (i >> 16); return i - (i >>> 1);
。 - Joeyi
右移一位后,重复执行 { ++l; }
直到 i
为 0。 - Lee Daniel Crockeri>>32
。不过由于Java只有32位整数,所以没问题。对于C/C++来说,需要考虑这个问题。 - Zoso#define M_LOG2E 1.44269504088896340736 // log2(e)
inline long double log2(const long double x){
return log(x) * M_LOG2E;
}
(乘法可能比除法更快)
log2(int n) = 31 - __builtin_clz(n)
log10()
是C标准中定义的函数,所以编译器可以对其进行特殊处理,包括预先计算结果,这也是@Johannes建议的内容。 - caflog
,但我已经多次看到使用 sqrt
进行这样的优化。 - Carl Norumlog10(2)
。 - cafuint32_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
,因为它可能完全在硬件中计算,因此速度更快。
还要查看可能的重复内容 如何在C++中执行整数log2()?
uint16_t log2(uint32_t n) {//but truncated
if (n==0) throw ...
uint16_t logValue = -1;
while (n) {//
logValue++;
n >>= 1;
}
return logValue;
}
基本上与 tomlogic 的相同。
log2(x) = log10(x) / log10(2)
您需要包含 math.h(C)或 cmath(C++)头文件。
当然,您需要遵循我们所知道的数学知识...只有数字>0。
例如:
#include <iostream>
#include <cmath>
using namespace std;
int main(){
cout<<log2(number);
}