C 为什么(无符号短)0x8000 0001不是1 65535?

C 为什么(无符号短)0x8000 0001不是1 65535?,c,casting,C,Casting,C 11 6.3.1.3,对于铸件: 否则,如果新类型是无符号的,则会通过重复地将新类型中可以表示的最大值加上或减去一个值来转换该值,直到该值在新类型的范围内 当我尝试 printf("%d", (unsigned short) 0x80000001); 我希望结果是65535,但我得到了1。 为什么在这种情况下返回1?USHRT\u MAX,在OP的情况下是65535(无符号短)0x80000001根据引用的C 11 6.3.1.3转换为1 unsigned short 1肯定会根据整数提升

C 11 6.3.1.3,对于铸件:

否则,如果新类型是无符号的,则会通过重复地将新类型中可以表示的最大值加上或减去一个值来转换该值,直到该值在新类型的范围内

当我尝试

printf("%d", (unsigned short) 0x80000001);
我希望结果是
65535
,但我得到了
1

为什么在这种情况下返回
1

USHRT\u MAX
,在OP的情况下是65535<代码>(无符号短)0x80000001根据引用的C 11 6.3.1.3转换为1

unsigned short 1
肯定会根据整数提升转换为
int 1
,作为参数的一部分。。。功能。这与打印的
%d“
“1”
相匹配。

  • 0x80000001
    =
    2147483649
  • unsigned short
    的最大值为
    65535
    。比这多一个是
    65536
  • “该值通过反复…减去比最大值多一个值来转换”
  • 反复减去,直到范围内的值(小于65536)与模数相同
  • 2147483649%65536
    =
    1

但这是形式理论-在实践中,这与简单地取
0x8000001
的最低16位非常相同,这是
0x0001

的值
无符号短
的最大值是
0xFFFF
。在此转换过程中,您将丢失一些位。比最大无符号短65535多一个将是。。。65536,又名。0x10000。取0x80000001并持续添加0x10000,直到“值在新类型的范围内”。这将发生在无符号溢出时,此时剩下的是0x00000001。该值在0x0的范围内。。0xFFFF,这就是你得到的结果:1。“我期望结果是65535”这是一个相当奇怪的期望,你能解释一下吗?因为我认为cast操作符会尽可能地保留值。但是现在我认为@WhozCraig是对的,我也误解了第6.3.1.3节