题目重点:把有符号32位整数转小写十六进制,负数按补码位模式输出。
题意与假设
这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。
- 训练signed32输入,返回无0x前缀、小写、不保留多余前导零;负数输出32位二进制补码对应的8位hex,0为0。
- 若题面要求数学负号形式−1,结果是另一个合同;本例明确补码而非负号。
解题路线
- 先与2^32−1做mask,把位模式解释为0..2^32−1无符号整数。Python负数右移符号扩展,若直接while n右移可能永不变0。
- 每轮取低4位n&15,对应0..f字符,再无符号右移4;得到从低位到高位,最后reverse。四位对应16进制一位。
- 0单独返回,避免空输出;正数自然没有前导零,负数最高bit1因此恰好8位。
- 限定输入范围,不能默默截断超过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端序变化?
