无法理解C程序输出

时间:2014-04-22 08:56:16

标签: c

我正在制作一些基本程序,我制作了这个程序

 #include<stdio.>
 int main()
 {
   printf("%d\n",-1>>4);
   return 0;
 }

output = -1

我无法理解它是如何发生的?

是-1,首先补充2,然后进行移位操作,然后再进行2次补码以产生结果。

我也想知道这个输出是怎么来的

int main()
{
 unsigned int a=4;
 printf("%d\n",-a>>4);
 return 0;   
}

result = 268435455

3 个答案:

答案 0 :(得分:4)

首先,您正在做的事情是不可移植的。

ISO C11陈述,6.5.7 Bitwise shift operators

  

E1&gt;的结果&gt; E2是E1右移E2位位置。如果E1具有无符号类型   或者如果E1具有带符号类型和非负值,则结果的值为积分   部分E1 / 2 ^ E2的商。 如果E1有签名类型和负值,则   结果值是实现定义的。

这样做是不明智的。

可能发生的事情是你有一个实现可以保留负值的符号。虽然>>通常可以在左侧以零比特移位(并且必须为无符号或有符号非负值而这样做),但您的实现可以检测到负数并转换为一个-bits进入左起第二位,左边的位保持不变。

这意味着-1(例如:二进制1111 1111 1111 1111仍然在右移之后具有该位模式。

您必须检查特定实现的文档(标准的附录J要求实现以记录他们对实现定义的行为的选择)。

您也可以使用一些更好的样本值来测试它,例如二进制1100 0000 0000 0000右移一位,然后看看会出现什么(当然,实现说明应该是最终来源)。 / p>


举例来说,gcc文档提供了此信息here。由于您提及使用4.6.3,因此4.6.4手册可能是最接近的。

该页面上的GCC 4.6.4 Manual (also in PDF or PostScript or an HTML tarball)链接包含一个名为C implementation-defined behaviour的部分,其中部分声明:

  

对有符号整数进行一些按位运算的结果(C90 6.3,C99 6.5)。

     

按位运算符作用于值的表示,包括符号和   值位,其中符号位被认为紧接在最高值之上   位。签名'&gt;&gt;'通过符号扩展对负数进行处理。

这意味着它就像我解释的那样,左边的位置影响到第二个最左边的位:

enter image description here


您在以下情况下看到不同价值的原因:

unsigned int a=4;
printf("%d\n",-a>>4);

是因为-a由于某种原因我并不完全确定,被视为-4的无符号表示。你可以看到:

#include <stdio.h>
int main()
{
    unsigned int a=4;
    printf("%09x\n",((unsigned int)(-a))>>1);
    printf("%09x\n",(-a)>>1);
    printf("%09x\n",(-((int)a))>>1);
    return 0;
}

输出(注释):

07ffffffe  # explicit unsigned int
07ffffffe  # seemingly treated as unsigned int

0fffffffe  # explicit int

怀疑这与整数促销和ISO C11 6.5 Expressions中详述的常规算术转换有关,但我认为这远远超出原始问题的范围

答案 1 :(得分:2)

-1具有二进制表示(假设2&#39; s补码):

11111111111111111111111111111111       // All ones, 32 of them if we assume 32 bit ints

当右移有符号数字时,如果符号位为1,则编译器似乎会移入1。

11111111111111111111111111111111       // All ones, 32 of them if we assume 32 bit ints
^^^^ These 4 are new

如您所见,数字保持不变,-1。

答案 2 :(得分:0)

-1是以位为单位的FFFFFFFF,所以当你右移任何位时它仍然是FFFFFFFF,即-1