我有 5 个不同的值,它们保存为 10010 之类的位。我从数据库中将值作为 Int 获取(无法更改),所以就像 24 表示 11000 我知道我可以通过使用在这里获得最大的位
if ((decbin($d) & 16) == 16)
但如果第一个是 0,我将不得不检查下一位,如果是 0,我将不得不...
所以毕竟我会有一个ifs块,如果有更多的位,这个块就更大。有没有一种简单的方法可以用 1 获取最高位的“id”(或值,无关紧要)?
我有 5 个不同的值,它们保存为 10010 之类的位。我从数据库中将值作为 Int 获取(无法更改),所以就像 24 表示 11000 我知道我可以通过使用在这里获得最大的位
if ((decbin($d) & 16) == 16)
但如果第一个是 0,我将不得不检查下一位,如果是 0,我将不得不...
所以毕竟我会有一个ifs块,如果有更多的位,这个块就更大。有没有一种简单的方法可以用 1 获取最高位的“id”(或值,无关紧要)?
是的。计算以 2 为底的对数,floor
它:
$highbit = floor(log($d, 2));
例如,如果$highbit
为 5,则表示第 5 位是最高位设置为 1。
整数中设置的最高位等于该整数的以 2 为底的整数对数。
虽然在汇编程序和 C 中存在许多不同的实现方式,但或多或少有效率,但在 PHP 中实现它的最简单方法可能是实际使用对数。
log() 函数肯定不是解决问题的最有效方法,但是当您使用脚本语言时,它可能不会比实现“更好”算法之一慢(而且很可能更快)在 PHP 中有 2 打语句。
因此:
$highestbit = (int)(log($value,2));
有趣...必须立即检查舍入问题,但在高达 1'000'000 的范围内没有发现任何问题,尽管我的测试代码揭示了较少原生基数的问题,例如 3:
3^5 = 243 但 floor(log(243, 3)) 给出 4
def hibit(v):
""" uint v -> highest bit: 0101 -> 0100, 01xxxx -> 010000 """
# cf http://graphics.stanford.edu/~seander/bithacks.html
v |= v >> 1
v |= v >> 2
v |= v >> 4
v |= v >> 8
v |= v >> 16
return v ^ (v >> 1)
for v in range(0, 9+1) + range(2**31-1, 2**31+2):
print v, hibit(v)