You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

关于《A book on C》中提取32位表达式间隔位函数的疑问

解答《A book on C》第7章第6题的两个疑问

我来帮你拆解这两个疑问,这类底层位操作题确实容易因为表述模糊让人困惑:

1. 「extract every other bit position」的具体含义

这个表述的标准理解是:从32位值中每隔一位提取一个比特,最终将这16个提取出的比特按原顺序组成一个16位结果。通常有两种常见的提取规则(题目没明确的话,一般默认取奇数索引位,这里的索引从0开始,bit0是最低位):

举你给出的32位例子:00000001 00000000 00000000 10011110(对应十六进制0x10009E)

  • 如果提取所有奇数索引位(bit31, bit29, bit27,..., bit1):
    逐个提取对应位置的比特:
    bit31=0, bit29=0, bit27=0, bit25=0, bit23=0, bit21=0, bit19=0, bit17=1
    bit15=0, bit13=0, bit11=0, bit9=0, bit7=1, bit5=0, bit3=1, bit1=1
    把这些比特按顺序拼接成16位,结果就是00000001 00001011(十六进制0x10B,十进制267)
  • 如果是提取偶数索引位(bit30, bit28,..., bit0):
    提取后得到的比特是:
    bit30=0, bit28=0,..., bit16=0;bit14=0,..., bit8=0;bit6=0, bit4=1, bit2=1, bit0=0
    拼接结果是00000000 00001100(十六进制0x0C,十进制12)

一般这类题目默认取奇数索引位(高位方向的每隔一位),你可以结合上下文或者后续测试用例验证。

2. 兼容16位(2字节)字长机器的处理方式

16位机器的核心限制是:原生int类型只有16位,无法直接存储32位值。解决这个矛盾的思路是用两个16位变量模拟32位值,拆分处理后再合并结果:

  • 把32位输入拆成高16位和低16位两个部分,用两个unsigned int(16位)存储
  • 分别对高16位和低16位执行“提取每隔一位”的操作:
    比如对16位值提取奇数位,可以用位掩码0xAAAA(二进制1010101010101010)与操作,然后右移1位,得到8位结果
  • 把高16位处理后的8位结果左移8位,和低16位处理后的8位结果做或操作,最终得到16位的返回值

举个适配16位机的代码思路:

unsigned short extract_32bit(unsigned short high, unsigned short low) {
    // 处理高16位:提取奇数位,右移1位得到8位
    unsigned short high_part = (high & 0xAAAA) >> 1;
    // 处理低16位:提取奇数位,右移1位得到8位
    unsigned short low_part = (low & 0xAAAA) >> 1;
    // 合并成16位结果
    return (high_part << 8) | low_part;
}

如果是在32位机上,直接用32位变量处理即可,比如用掩码0xAAAAAAAA与原数,再右移1位得到16位结果。

确实,《A book on C》的部分习题表述偏简洁,不像Kochan的书那样直白,遇到这种情况结合底层位操作的常见场景来推导就好。

内容的提问来源于stack exchange,提问作者SON TO

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 07:18:22