IT

C / C ++에서 log base (2)를 작성하는 방법

lottoking 2020. 9. 8. 08:13
반응형

C / C ++에서 log base (2)를 작성하는 방법


log (base 2) 함수를 작성하는 방법이 있습니까?

C 언어에는 2 개의 내장 기능이 있습니다 .-- >>

1. log베이스 e.

2. log10베이스 10;

하지만 2 진법의 로그 함수가 필요합니다.


간단한 수학 :

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

여기서 y 는 무엇이든 가능하며 표준 로그 함수의 경우 10 또는 e 입니다.


적분 결과를 찾고있는 값에 최고 높은 비트를 결정하고 그 위치를 반환 할 수 있습니다.


C99에는 ( float 및 long double)이 있습니다.log2log2flog2l


#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)

http://en.wikipedia.org/wiki/Logarithm에 근처대로 :

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

의미하는 것은 :

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

빠르게 생성 할 URL 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하는 가 완전히 하드웨어에서 계산 할 수 있기 때문에 더 빠를 수 있습니다.

가능성도 가능성이 C ++에서 정수 log2 ()를 수행하는 방법은 무엇입니까?


log2(x) = log10(x) / log10(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 과 동일 합니다.


math.h (C) 또는 cmath (C ++)를 포함해야합니다. 물론 우리가 알고있는 수학을 따라야합니다 ... 숫자> 0 만

예 :

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

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

나는 가장 중요한 비트의 위치보다 더 정밀해야했고, 내가 사용하고있는 마이크로 컨트롤러에는 수학 라이브러리가 없었습니다. 양의 정수 값 인수에 대해 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를 계산해야했습니다.

온도 = (((uint32_t) N) * approx_log_base_2_N_times_256) / 512;

16 비트 값은 모두 2 % 이상 떨어지지 않았습니다.


기본 수학 과정을 참조하십시오 log n / log 2. 당신이 선택의 여부는 중요하지 않습니다 log또는 log10이 경우로 나누어 log새로운베이스의 트릭을 수행합니다.


Ustaman Sangat의 개선 된 버전

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

    return val;
}

참고 URL : https://stackoverflow.com/questions/3064926/how-to-write-log-base2-in-cc

반응형