C ++如何获得一个变量的位长度?
这个问题在这里已经有了答案:
警告:数学提前。 如果你很娇气,可以直接跳到TL; DR。
你真正想要的是设定的最高位。 让我们写出二进制数字10001 11010111的实际含义:
x = 1 * 2^(12) + 0 * 2^(11) + 0 * 2^(10) + ... + 1 * 2^1 + 1 * 2^0
其中*
表示乘法, ^
是取幂。
你可以这样写
2^12 * (1 + a)
其中0 < a < 1
(准确地说, a = 0/2 + 0/2^2 + ... + 1/2^11 + 1/2^12
)。
如果取对数(以2为底),让我们用log2
表示这个数字
log2(2^12 * (1 + a)) = log2(2^12) + log2(1 + a) = 12 + b.
由于a < 1
我们可以得出结论1 + a < 2
,因此b < 1
。
换句话说,如果你取log2(x)
并舍入它,你将得到2的最大幂(在这个例子中是12)。 由于电源开始从0开始计数,因此比特数比该功率多一个,即13。
TL; DR :
表示数字x
所需的最小位数由下式给出
numberOfBits = floor(log2(x)) + 1
unsigned bits, var = (x < 0) ? -x : x;
for(bits = 0; var != 0; ++bits) var >>= 1;
这应该为你做。
你正在寻找数字中最重要的位。 让我们暂时忽略负数。 我们怎么找到它? 那么,让我们看看在整数为零之前需要将多少位设置为零。
00000000 00000000 00010001 11010111
00000000 00000000 00010001 11010110
^
00000000 00000000 00010001 11010100
^
00000000 00000000 00010001 11010000
^
00000000 00000000 00010001 11010000
^
00000000 00000000 00010001 11000000
^
00000000 00000000 00010001 11000000
^
00000000 00000000 00010001 10000000
^
...
^
00000000 00000000 00010000 00000000
^
00000000 00000000 00000000 00000000
^
完成! 在13位之后,我们已经清除了所有这些。 现在我们该如何做到这一点? 那么,表达1<< pos
是偏移1位在pos
位置。 所以我们可以检查if (x & (1<<pos))
,如果是true,则删除它: x -= (1<<pos)
。 我们也可以在一个操作中做到这一点: x &= ~(1<<pos)
。 ~
让我们得到补充:所有的pos
位置为零,而不是反过来。 x &= y
将x &= y
的零位复制到x中。
现在我们如何处理签名数字? 最简单的就是忽略它: unsigned xu = x;