快速求取Log2

方法一

// 来自lua源码,移植性好
int luaO_log2 (unsigned int x) {
  static const lu_byte 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];
}

方法二

// 利用float存储时,在内存中直接保存了指数值,根据其内存分布,直接取指数
// 移植性受到float内存分布的限制,但目前来说都是IEEE标准的
typedef unsigned long uint32;
typedef long int32;
 
static inline int32 ilog2(uint32 x) {
	return ilog2((float)x);
}
 
// integer log2 of a float
static inline int32 ilog2(float x)
{
	uint32 ix = (uint32&)x;
	uint32 exp = (ix >> 23) & 0xFF;
	int32 log2 = int32(exp) - 127;
 
	return log2;
}

方法二

// 汇编实现,简单直接,移植性欠缺一些
static inline int32 ilog2_x86(uint32 x)
{
	int32 retval;
	__asm {
		bsr eax, x
		mov retval, eax
	}
	return retval;
}
c/fastlog2.txt · 最后更改: 2012/01/12 14:27 由 admin
 
Recent changes RSS feed Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki