求一个整数是2的几次幂(极其高效)

来源:互联网 发布:java怎么做图形界面 编辑:程序博客网 时间:2024/04/28 05:11

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的幂

貌似很高效。留记录。
原创粉丝点击