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

时间:2010-06-17 19:25:51

标签: c++ c

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

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

1。log是基础e。

2. log10基数10;

但是我需要基数2的日志功能。如何计算。

14 个答案:

答案 0 :(得分:181)

简单的数学:

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

其中 y 可以是任何内容,标准日志功能为10或 e

答案 1 :(得分:51)

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

答案 2 :(得分:49)

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

答案 3 :(得分:40)

#define M_LOG2E 1.44269504088896340736 // log2(e)

inline long double log2(const long double x){
    return log(x) * M_LOG2E;
}

(乘法可能快于除法)

答案 4 :(得分:11)

log2(int n) = 31 - __builtin_clz(n)

答案 5 :(得分:9)

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

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

这意味着:

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

答案 6 :(得分: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];

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

另请查看可能重复的How to do an integer log2() in C++?

答案 7 :(得分:2)

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

答案 8 :(得分:2)

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

tomlogic的基本相同。

答案 9 :(得分:2)

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

示例:

#include <iostream>
#include <cmath>
using namespace std;

int main(){
    cout<<log2(number);
}

答案 10 :(得分:1)

我需要更高精度,只有最高位的位置,而我使用的微控制器没有数学库。我发现只使用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%

答案 11 :(得分:1)

以上所有答案均正确。如果有人需要,下面的我的回答可能会有帮助。我已经在许多使用C语言解决的问题中看到了这一要求。

log2 (x) = logy (x) / logy (2)

但是,如果您使用的是C语言,并且希望结果为整数,则可以使用以下代码:

int result = (int)(floor(log(x) / log(2))) + 1;

希望这会有所帮助。

答案 12 :(得分:0)

参考您的基础数学课程log n / log 2。在这种情况下,选择loglog10并不重要,除以新基数的log就可以了。

答案 13 :(得分:0)

Ustaman Sangat所做的改进版本

static inline uint64_t
log2(uint64_t n)
{
    uint64_t val;
    for (val = 0; n > 1; val++, n >>= 1);

    return val;
}