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

有符号/无符号整数运算取值范围对abs输出结果的影响疑问

现象底层原理解答

核心前置知识

  • C语言默认做整数运算前会执行整数提升:所有宽度小于int的整型(包括int8_t/uint8_t/int16_t在32位/64位系统下都满足),都会先转换为int再参与运算
  • 有符号整型用补码存储,小宽度有符号整型转大宽度有符号整型时会做符号扩展,保持数值不变而非保持二进制位不变
  • abs函数的参数是int类型,返回值也是int类型

场景1:temp1、temp2为int8_t类型

int8_t是8位有符号整型,取值范围-128 ~ 127:

  • 0x3a 对应十进制值 58,在范围内,值保持为58
  • 0xfb 二进制最高位为1,作为补码对应十进制值 251 - 256 = -5

运算过程:
temp1 - temp2 = 58 - (-5) = 63,abs(63) = 63,十六进制为0x3f,和输出一致。

场景2:temp1、temp2为int16_t类型

int16_t是16位有符号整型,取值范围-32768 ~ 32767:

  • 0x3a 对应值 58
  • 0xfb 十进制为251,在正范围内,值保持为251

运算过程:
temp1 - temp2 = 58 - 251 = -193,abs(-193) = 193,十六进制为0xc1,和输出一致。

场景3:temp1、temp2为uint8_t类型

uint8_t是8位无符号整型,取值范围0 ~ 255:

  • 0x3a 对应值 58
  • 0xfb 对应值 251

运算过程:
两个值先提升为int再运算,58 - 251 = -193,abs(-193) = 193 = 0xc1,和输出一致。


强制转换场景的结果解释

你将int8_t类型的变量强制转换为int16_t时,遵循有符号类型转换规则:

  • 原int8_t类型的temp1值为58,转int16_t后仍为58
  • 原int8_t类型的temp2值为-5,转int16_t时做符号扩展,值仍为-5,而非你预期的251(只有无符号转换/截断才会保持二进制位不变)

运算过程还是58 - (-5) = 63,abs(63) = 0x3f,和实际输出一致。
如果要得到0xc1的结果,你需要将int8_t的变量先强制转换为uint8_t再转int16_t,保证二进制位按无符号解析:

printf("%x", abs((int16_t)(uint8_t)temp1 - (int16_t)(uint8_t)temp2));

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 07:54:03