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

C++中有符号与无符号整数除法异常现象原因咨询

为什么有符号与无符号整数混合运算时乘除结果表现不同?

先看测试代码:

#include <iostream>
using namespace std;

int main(int argc, char *argv[]) {
    int i = -100;
    unsigned u = 10;

    cout << "i = " << i << endl;

    i *= u;
    cout << "i*10 = " << i << endl;

    i /= u;
    cout << "i = " << i << endl;

    return 0;
}

运行输出:

i = -100
i*10 = -1000
i = 429496629

核心原因:C++整数转换规则 + 运算结果的类型兼容性

C++明确规定:当有符号整数(int)和无符号整数(unsigned)混合运算时,有符号整数会先被隐式转换为无符号整数类型,再执行运算,最后将结果赋值回原变量(int)。两者表现差异的本质是:运算后的无符号结果,在转换回int时的行为完全不同。

乘法步骤的“巧合”符合预期

  1. 执行i *= u时,i=-100(int)先转成unsigned:在32位系统中,-100的无符号等价值为2^32 - 100 = 4294966196。
  2. 乘以10后得到4294966196 * 10 = 42949661960,该值超出32位unsigned的最大值(2^32 -1 = 4294967295),无符号运算会自动取模2^32,结果为4294966296(即2^32 - 1000)。
  3. 把这个无符号值赋值回int:32位int的范围是-2^31 ~ 2^31-1,4294966296的二进制最高位为1(属于负数补码范围),因此会被解释为-1000,刚好符合预期。

除法步骤的结果超出“巧合”范围

  1. 此时i=-1000(int),执行i /= u时,i先转成unsigned,值为2^32 - 1000 = 4294966296。
  2. 除以10得到4294966296 / 10 = 429496629,这个值是正数且小于32位int的最大值2147483647。
  3. 把这个无符号值赋值回int时,因为它在int的正范围内,所以直接保留为正数429496629,而非预期的-100。

解决办法

通过显式类型转换,强制让运算在有符号整数范围内执行:

i /= (int) u; // 把u转成int后再运算,-1000/10=-100,结果符合预期

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 04:48:39