简体   繁体   English

无法理解C程序输出

[英]Can't understand C program output

I was making some basic programs and i made this program 我正在编写一些基本程序,并且我编写了该程序

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

output = -1 输出= -1

i could not understand how it happens ? 我不明白这是怎么回事?

is -1 is 2's complemented first and then shift operation is done .and then again 2's complement is done to produce the result. 是-1是2的补数,然后进行移位运算。然后再进行2的补数以产生结果。

i also want to know how this output comes 我也想知道这个输出是怎么来的

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

result = 268435455 结果= 268435455

For a start, what you're doing is non-portable. 首先,您要做的是不可移植的。

ISO C11 states, in 6.5.7 Bitwise shift operators : ISO C11规定,在6.5.7 Bitwise shift operators

The result of E1 >> E2 is E1 right-shifted E2 bit positions. E1 >> E2的结果是E1右移E2位位置。 If E1 has an unsigned type or if E1 has a signed type and a nonnegative value, the value of the result is the integral part of the quotient of E1 / 2^E2 . 如果E1具有无符号类型或E1具有符号类型和非负值,则结果的值是E1 / 2 ^ E2的商的整数部分。 If E1 has a signed type and a negative value, the resulting value is implementation-defined. 如果E1具有带符号的类型和负值,则结果值是实现定义的。

So it's not wise to do that. 因此,这样做是不明智的。

What's possibly happening is that you have an implementation that preserves sign on the negative values. 可能发生的情况是,您有一个在负值上保留符号的实现。 Whereas >> may normally shift in zero bits on the left hand side (and must do so for an unsigned or signed-nonnegative value), your implementation could detect a negative number and shifts in one-bits into the second-from-left position, leaving the left bit untouched. >>通常可能会在左侧移零位(并且对于无符号或带负号的负数, 必须这样做),但是您的实现可能会检测到负数并将一位移入从左数第二个位置,剩下的部分保持不变。

That means -1 (eg: binary 1111 1111 1111 1111 ) will still have that bit pattern after a right-shift. 这意味着-1 (例如:二进制1111 1111 1111 1111 )在右移后仍将具有该位模式。

You would have to examine the documentation for your particular implementation to be sure (Appendix J of the standard requires implementations to document their choices for implementation-defined behaviours). 您必须检查特定实现的文档以确保(标准的附录J要求实现记录实现定义的行为的选择)。

You could also test it with a few better sample values like binary 1100 0000 0000 0000 right-shifted by one bit, and see what comes out (though, of course, the implementation notes should be the definitive source). 您还可以使用一些更好的样本值(例如二进制1100 0000 0000 0000右移一位)对其进行测试,然后看看会得出什么结果(尽管当然,实现说明应该是确定的来源)。


By way of example, the gcc documentation provides this information here . 举例来说, gcc文档在此处提供了此信息。 Since you mention you're using 4.6.3, the 4.6.4 manuals are probably the closest. 由于您提到使用的是4.6.3,因此4.6.4手册可能是最接近的。

The GCC 4.6.4 Manual (also in PDF or PostScript or an HTML tarball) link on that page contains a section entitled C implementation-defined behaviour which states, in part: 该页面上的GCC 4.6.4 Manual (also in PDF or PostScript or an HTML tarball)链接包含标题为C implementation-defined behaviour部分,该部分部分指出:

The results of some bitwise operations on signed integers (C90 6.3, C99 6.5). 对有符号整数(C90 6.3,C99 6.5)进行一些按位运算的结果。

Bitwise operators act on the representation of the value including both the sign and value bits, where the sign bit is considered immediately above the highest-value value bit. 按位运算符作用于包括符号位和值位的值的表示形式,其中符号位被认为紧邻最高值位。 Signed '>>' acts on negative numbers by sign extension. 带符号的“ >>”通过符号扩展作用于负数。

That means it acts as I explained, with the left bit staying put and affecting the second-most left bit: 这意味着它的作用如我所解释,左位保持不变影响到第二个最左位:

在此处输入图片说明


The reason why you're seeing a different value with: 您之所以看到不同的值的原因是:

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

is because -a is, for some reason I'm not entirely certain of, being treated as the unsigned representation of -4. 因为-a由于某种原因我不确定,所以将-a视为-4的无符号表示。 You can see that with: 您可以通过以下方式看到它:

#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;
}

which outputs (annotated): 输出(带注释):

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

0fffffffe  # explicit int

I suspect this has to do with integer promotions and the usual arithmetic conversions detailed in ISO C11 6.5 Expressions but I think that's moving well beyond the scope of the original question. 怀疑这与整数提升和ISO C11 6.5 Expressions详细介绍的通常的算术转换有关,但我认为这已经超出了原始问题的范围。

-1 has the binary representation (assuming 2's complement): -1具有二进制表示形式(假定2的补码):

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

When right-shifting signed numbers, your compiler seems to shift in 1 if the sign bit is 1. 右移带符号的数字时,如果符号位为1,则编译器似乎将移入1。

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

As you can see, the number stays the same, -1. 如您所见,数字保持不变,-1。

-1是FFFFFFFF,按位,因此当您右移任何位时,它仍将是FFFFFFFF,即-1

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM