为何《TCPPPL》中提取32位long中间16位的代码不是取最后16位?
为什么
(a>>8)&0xffff提取的是32位long的中间16位? 嘿,这个问题问得特别棒!咱们一点点拆解这个代码,你马上就能搞清楚自己的误解在哪里啦。
首先,先明确32位long类型的位布局:我们把它从最高位到最低位标记为 bit31 到 bit0,总共32位。如果用十六进制表示的话,一个32位long可以写成 0xWWXXYYZZ,其中:
WW是最高8位(bit31-bit24)XX是次高8位(bit23-bit16)YY是中间8位(bit15-bit8)ZZ是最低8位(bit7-bit0)
现在来看这段代码:
unsigned short middle(long a){ return (a>>8)&0xffff;}
我们分两步分析:
- 右移8位操作
a>>8:把整个32位的数向右移动8位,相当于把每个位的位置都往低位移8位。这时候:- 原来的
WWXXYYZZ会变成00WWXXYY(假设是无符号移位,或者对于正数的有符号移位,结果一致) - 原来的中间16位(
XXYY,对应bit23-bit8)现在跑到了整个数的低16位(bit15-bit0)
- 原来的
- 掩码操作
&0xffff:0xffff是16位的全1掩码,它会保留结果的低16位,把更高位清零。所以这一步就把刚才移到低16位的XXYY保留下来了——这正好是原32位long的中间16位!
那如果要提取最后16位(也就是YYZZ),代码应该是直接 a&0xffff,不需要右移8位。咱们用具体数值举个例子:
假设 a = 0x12345678(32位):
- 直接
a&0xffff得到0x5678,这是最后16位 (a>>8)&0xffff得到0x3456,这是原数的中间16位(0x34和0x56)
你之前的误解应该是误以为右移8位会保留高位,但实际上右移是把高位往低位移,原来的中间段会落到低16位,再通过掩码就提取出了中间16位啦。
内容的提问来源于stack exchange,提问作者Ashutosh Tiwari
相关产品推荐
相关产品推荐

