求一个整数是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