SWE · Coding

Meta 整数转Hex:负数补码与四位分组

把有符号32位整数转小写十六进制,负数按补码位模式输出。

题目重点:把有符号32位整数转小写十六进制,负数按补码位模式输出。

题意与假设

这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。

  • 训练signed32输入,返回无0x前缀、小写、不保留多余前导零;负数输出32位二进制补码对应的8位hex,0为0。
  • 若题面要求数学负号形式−1,结果是另一个合同;本例明确补码而非负号。

解题路线

  1. 先与2^32−1做mask,把位模式解释为0..2^32−1无符号整数。Python负数右移符号扩展,若直接while n右移可能永不变0。
  2. 每轮取低4位n&15,对应0..f字符,再无符号右移4;得到从低位到高位,最后reverse。四位对应16进制一位。
  3. 0单独返回,避免空输出;正数自然没有前导零,负数最高bit1因此恰好8位。
  4. 限定输入范围,不能默默截断超过32位整数却声称忠实转换。独立oracle使用signed int.to_bytes(4,big)再hex验证,而非再实现同一位拆分。

手动走一遍

26=0x1a输出1a;−1位模式全1输出ffffffff;−2输出fffffffe;最小−2^31输出80000000。

Python 参考实现

下面的代码按上文假设实现,适合本地运行并追加自己的测试用例。

代码区可横向滚动;使用键盘时,先聚焦代码区再按方向键查看。

def hex32(number):
    """Signed 32-bit input, negative represented as unsigned two's-complement bits."""
    if not -(1<<31)<=number<(1<<31):raise ValueError('signed 32-bit required')
    unsigned=number & ((1<<32)-1)
    if unsigned==0:return '0'
    digits='0123456789abcdef';out=[]
    while unsigned:
        out.append(digits[unsigned&15]);unsigned>>=4
    return ''.join(reversed(out))

复杂度

固定32位最多8轮,O(1)时间/空间含定长输出;推广b位则O(b/4)字符工作和输出。不要把任意宽度版本也视常数。

易错点与追问

容易失分的边界

  • 负整数直接算n%16/有符号右移没有终止。
  • 用abs(n)转换后加负号与补码合同不同。

继续深挖

  • 要求64位时mask与范围怎样一起调整?
  • 大小端影响bytes展示顺序,但整数标准hex表示为何不随CPU端序变化?
✓已复制微信号!