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

K&R习题3.4:补码下itoa无法处理最大负整数问题咨询

K&R 习题3.4 解答

故障原因理解正确性确认

你的理解完全正确。
补码体系下有符号整数的取值范围天然不对称:N位补码可表示的范围是[-2^(N-1), 2^(N-1)-1],最大负整数没有对应的正数值,对其执行取负操作属于有符号整数溢出,是C标准规定的未定义行为,绝大多数编译器实现中该操作的结果仍然是原最大负整数。
原函数中if ((sign=n)<0) n=-n;的逻辑在n等于INT_MIN(即最大负整数)时,n取负后仍然为负数,后续n%10、n/=10的运算逻辑不符合预期,最终会生成错误的字符串结果,和你的分析完全一致。

修改方案说明

你提出的「先减1转换再修正个位」的方案是可行的,实现时可以直接引入<limits.h>头文件的INT_MIN宏做判断,不需要手动适配不同位宽的机器,兼容性更强。
除此之外还有更简洁的通用方案:利用无符号整数的取值范围覆盖所有有符号整数的绝对值,全程用无符号整数做运算,避免溢出问题,修改后的代码如下:

#include <limits.h>

void itoa(int n, char s[]){
  int i, sign;
  unsigned int num;

  sign = n;
  // 负数转对应无符号绝对值,无溢出问题
  num = (n < 0) ? (unsigned int)(-n) : (unsigned int)n;
  i = 0;
  do {
    s[i++] = num % 10 + '0';
  } while ((num /= 10) > 0);
  if (sign < 0)
    s[i++] = '-';
  s[i] = '\0'; // 原代码此处为'\n'属于笔误,应为字符串结束符
  reverse(s);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 12:24:01