假设有一个变量int x。它的大小是4个字节,即32位。
然后我为这个var赋值,x = 4567(二进制10001 11010111);现在,在内存中它应该是这样的:
00000000 00000000 000 10001 11010111
有没有办法获得重要的位长度。在我的例子中,比特长度将是13(我用粗体标记它们)。 如果我使用sizeof(x)它返回4个字节,其大小为int。如何只获得代表数字的位数(后面没有不必要的零)?
答案 0 :(得分:6)
警告:数学提前。如果你感到娇气,请跳到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
答案 1 :(得分:5)
unsigned bits, var = (x < 0) ? -x : x;
for(bits = 0; var != 0; ++bits) var >>= 1;
这应该为你做。
答案 2 :(得分: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
是在pos
位置上移位的1位。我们可以检查if (x & (1<<pos))
,如果是,请将其删除:x -= (1<<pos)
。我们也可以在一个操作中执行此操作:x &= ~(1<<pos)
。 ~
为我们提供补充:所有pos
位设置为零而不是相反的方式。 x &= y
将y的零位复制到x。
现在我们如何处理签名号码?最简单的是忽略它:unsigned xu = x;