short int c未理解的整数环绕/短int反转,赋值和打印之间的差异

时间:2017-03-09 17:02:48

标签: c types integer integer-overflow

以下代码片段

short int k = -32768;
printf("%d \n", -k);
k=-k;
printf("%d \n", k);

打印

32768 
-32768

我认为两张照片都是平等的。 有人可以解释一下差异是什么以及赋值k=-k导致环绕的原因吗?很难在网上找到解释,因为我真的不知道该怎么去谷歌。

3 个答案:

答案 0 :(得分:2)

好吧,要打印一个short,你需要使用长度修饰符。

将格式字符串更改为%hd

答案 1 :(得分:2)

因为SHRT_MIN = -32768SHRT_MAX = +32767。看看2的补充是如何工作的。

修改

实际上,根据C编程语言的国际标准(即Committee Draft — May 6, 2005,第50-51页)关于有符号整数:

  

对于有符号整数类型,对象表示的位应分为三组:值位,填充位和符号位。

     

不需要任何填充位;应该只有一个符号位。

     

作为值位的每个位应具有与相应无符号类型的对象表示中的相同位相同的值(如果在有符号类型中存在M个值位且在无符号类型中存在N,则M <0。 = N)。

     

如果符号位为零,则不会影响结果值。

     

如果符号位为1,则应以下列方式之一修改该值:

     
      
  • 符号位0的相应值被否定(符号和幅度);

  •   
  • 符号位的值为 - (2 N )(二进制补码);

  •   
  • 符号位的值为 - (2 N - 1)(补码)。

  •   
     

其中适用的是实现定义的,以及符号位为1且所有值位为零的值(前两个),或符号位和所有值位1(对于“补充”,是陷阱表示或正常值。在符号和幅度以及1的补码的情况下,如果该表示是正常值,则称为负零。

所以,换句话说,在你的情况下,似乎正在使用2的补码,但不应该假设它在所有平台和编译器中。

答案 2 :(得分:1)

-32768以十六进制表示法为800032768无法表示为带符号的16位数,因此编译器会将-k提升为int,其值为00008000。将此数字分配给16位变量时,高位会被截断,从而再次生成8000-32768