如何通过补码表示法实现任意进制负数转换及itob函数编写
补码表示下负十进制数转任意进制操作步骤
- 先确定对应整型的位宽:常规32位int型就按32位补码规则处理,64位整型按64位处理
- 第一步:将负数转换为等价值的无符号数,计算公式为:
等价无符号值 = 2^位宽 + 负数十进制值。比如32位int型的-5,等价无符号值就是2^32 -5 = 4294967291 - 第二步:把第一步得到的无符号数值按照常规的「除基取余,逆序排列」方法转换为目标进制即可
- 特殊说明:如果是转十六进制,每4位二进制对应1位十六进制位,可以直接按位拆分补码的二进制串转换,效率更高
举个实际例子:32位int型的-1转16进制
- 等价无符号值为2^32 -1 = 4294967295
- 除16取余得到的余数依次是15、15、15、15、15、15、15、15,对应十六进制字符f,逆序后结果为
ffffffff,和补码直接拆分结果一致
itob函数实现(C语言为例)
函数逻辑说明:
- 支持进制范围2~36,用0-9和a-z共36个字符表示每一位
- 直接将输入int强转为unsigned int,自动适配补码规则,不需要单独判断正负处理
- 除基取余收集每一位字符后手动逆序,避免依赖非标准库函数
void itob(int n, char s[], int b) { const char digits[] = "0123456789abcdefghijklmnopqrstuvwxyz"; int i = 0; unsigned int num = (unsigned int)n; // 进制不合法直接返回空串 if (b < 2 || b > 36) { s[0] = '\0'; return; } // 除基取余,先收集低位到高位 do { s[i++] = digits[num % b]; num /= b; } while (num > 0); // 十六进制可选补前导0到8位(对应32位int的完整十六进制长度),需要的话取消下方注释即可 // if (b == 16) { // while (i < 8) s[i++] = '0'; // } s[i] = '\0'; // 手动逆序字符串,转为高位在前的正常顺序 int left = 0, right = i - 1; while (left < right) { char temp = s[left]; s[left] = s[right]; s[right] = temp; left++; right--; } }
测试用例参考:
调用itob(-5, s, 16)得到结果fffffffb
调用itob(255, s, 2)得到结果11111111
调用itob(1234, s, 8)得到结果2322
内容的提问来源于stack exchange,提问作者PwNzDust
相关产品推荐
相关产品推荐

