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

为何uint16_t类型变量x*x会得到错误结果?

问题原因解析

核心原因:整数提升与有符号整数溢出

我们一步步拆解问题:

  1. 变量类型自动提升
    执行x*x时,C语言的整数提升规则会生效:

    • x是uint16_t(无符号16位整数),最大值为0xFFFF(65535)。
    • 你的系统中int为32位,完全能容纳uint16_t的所有取值,因此x会被自动转换为有符号32位int参与运算。
  2. 乘法运算触发溢出
    65535 * 65535的结果是4294836225,但32位有符号int的取值范围仅为-2147483648到2147483647,这个结果远超上限,触发有符号整数溢出(属于C标准中的未定义行为,但GCC默认按补码回绕处理)。
    溢出后结果回绕为-131071,计算逻辑:4294836225 - 2^32 = -131071。

  3. 赋值时的符号扩展
    溢出后的-131071是32位有符号int值,赋值给uint64_t类型的pow时会触发符号扩展:

    • 因原数为负数,32位补码最高位是1,扩展到64位时高32位会全部填充为1,最终得到64位值0xfffffffffffe0001。
  4. printf格式符的误导
    你使用%ld格式符输出pow,%ld对应有符号长整型,会把0xfffffffffffe0001解析为有符号数,显示为-131071。若改用%lu(无符号长整型),就能输出正确的无符号值18446744073602795521。

解决方法回顾

将x强制转换为uint64_t后,运算会以64位无符号整数执行,不会触发溢出:

uint64_t pow = (uint64_t)x * x;

内容的提问来源于stack exchange,提问作者Bartłomiej Bury

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 05:33:14