1つの整数が2の何回のべき乗であることを求めます(きわめて効率的です)
まとめたものは比較しないで、記録しただけです.
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);
1つの数が2のべき乗であるかどうかを判断し、真であれば2のべき乗である:
#define is2power(a) (((a) & ((a)-1)) == 0)
余を求めるビット演算版が見つかりました...
#define dmod((a),(b)((a)&((b)−1))は、a%bが2であるべきべき乗に等しい
効率的なようです.記録を残す.