求一個整數是2的幾次冪(極其高效)


1.源自linux內核源碼中的一段(有匯編的,不過摘抄的c實現的,並做了一點變形)

匯編的不做比較,記錄下而已
Linux/arch/avr32/include/asm/page.h

 

/* Pure 2^n version of get_order */
static inline int get_order(unsigned long size)
{
        unsigned lz;

        size = (size - 1) >> PAGE_SHIFT;
        asm("clz %0, %1" : "=r"(lz) : "r"(size));
    return 32 - lz;
}

 

內核中的原版
Linux/arch/mn10300/include/asm/page.h

 

#define PAGE_SHIFT 12
/* Pure 2^n version of get_order */
static inline int get_order(unsigned long size) __attribute__((const));
static inline int get_order(unsigned long size)
{
        int order;

        size = (size - 1) >> (PAGE_SHIFT - 1);
        order = -1;
        do {
                size >>= 1;
                order++;
        } while (size);
        return order;
}

 

小變更后的:

static inline int get_order(unsigned long size)
{
    int order;
    size = (size - 1) >> (0);
    order = -1;
    do {
        size >>= 1;
        order++;
    } while (size);
    return order;
}

 

 

2.源自lua源碼中的一段

int luaO_log2 (unsigned int x) {
  static const unsigned char log_2[256] = {
    0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
    6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
    7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
    7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
    8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
    8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
    8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
    8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8
  };
  int l = -1;
  while (x >= 256) { l += 8; x >>= 8; }
  return l + log_2[x];
}

 

 

貌似純C的話,還是lua的這個函數快吧。

最近的一個小需求是,根據size值,變更為接近2的冪的一個數(還多虧看了下lua源碼。。。)。
1<<(luaO_log2(size)+1);
判斷一個數是否為2的冪,為真則為2的冪:
#define is2power(a) (((a) & ((a)-1)) == 0)

才發現求余的位運算版。。。
#define dmod((a), (b)) ((a)&((b)-1)) 等於 a%b  b要為2的冪

貌似很高效。留記錄。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM