求一个数取log2的较小的整数 Ilog2

最近在看recast&detour源码的时候有遇到许多数学上的算法问题,特此记录,以便以后查看。


举例:

Ilog2(8) = 3

Ilog2(15) = 3

Ilog2(16) = 4

思路:

从二进制角度看 即 右移几位 以后为1(最高位)

比如

8 = 1000b, 右移3位

15=1111b,右移3位

16=10000b,右移4位

源码:

inline unsigned int dtIlog2(unsigned int v)
{
	unsigned int r;
	unsigned int shift;
	r = (v > 0xffff) << 4; v >>= r;
	shift = (v > 0xff) << 3; v >>= shift; r |= shift;
	shift = (v > 0xf) << 2; v >>= shift; r |= shift;
	shift = (v > 0x3) << 1; v >>= shift; r |= shift;
	r |= (v >> 1);
	return r;
}

解析:

应用二分法的思想,将数进行移位。记 r 为需要右移的位数。

1)将此数与 0xffff 比较

        如果比 0xffff 大,说明至少需要右移16位;r = 16(即1<<4 = 10000b);并将此数右移16位进行更新。

        如果比 0xffff 小,什么都不做;r = 0。

2)将更新后的数与 0xff 比较

        如果比 0xff 大,说明至少需要右移8位;r += 8(即1<<3 = 1000b);并将此数右移8位进行更新。

        如果比 0xff 小,什么都不做;r += 0。

3)将更新后的数与 0xf(1111b)比较

        如果比 0xf 大,说明至少需要右移4位;r += 4(即1<<2 = 100b);并将此数右移4位进行更新。

        如果比 0xf 小,什么都不做;r += 0。

4)将更新后的数与 0x3(11b)比较

        如果比 0x3 大,说明至少需要右移2位;r += 2(即1<<1 = 10b);并将此数右移2位进行更新。

        如果比 0x3 小,什么都不做;r += 0。

5)将更新后的数(只剩下两个bit位 XXb )直接右移一位

        如果结果为1,r+=1。

        如果结果为0,r+=0。

        r即为最终结果。

  ps:此处 |= 即为 +=, 使用位运算更高效。 即 10000b | 1000b = 10000b + 1000b。 

参考:

https://github.com/recastnavigation/recastnavigation

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ivy_0709

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值