C语言 左移负移位计数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4945703/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 07:45:07  来源:igfitidea点击:

Left shifting with a negative shift count

c

提问by Ishq

What exactly happens here?

这里究竟发生了什么?

a << -5

a << -5

Obviously it doesn't right shift. But the book I'm reading states:

显然它不是右移。但我正在阅读的书指出:

On one machine, this expression actually does a left shift of 27 bits

在一台机器上,这个表达式实际上做了 27 位的左移

My question is; why? What causes a left shift of 27 bits? And what exactly happens when shifting with a negative shift count? Thank you.

我的问题是;为什么?是什么导致左移 27 位?当以负移位计数移位时究竟会发生什么?谢谢你。

回答by Lundin

Negative integers on right-hand side is undefined behavior in the C language.

右侧的负整数在 C 语言中是未定义的行为。

ISO 9899:2011 6.5.7 Bit-wise shift operators:

ISO 9899:2011 6.5.7 按位移位运算符:

The integer promotions are performed on each of the operands. The type of the result is that of the promoted left operand. If the value of the right operand is negativeor is greater than or equal to the width of the promoted left operand, the behavior is undefined.

对每个操作数执行整数提升。结果的类型是提升的左操作数的类型。如果右操作数的值为负或大于或等于提升的左操作数的宽度,则行为是 undefined

回答by Anand

As already answered by other members, it produces undefined behavior. What I would like to mention here is that you quote from the book ( "On one machine" ) seems to be partial. It does not generalize the behavior. The book might also have explained that the behavior is undefined as per the standard. BTW, I was just going through "The New C Standard - An Economic and Cultural Commentary" and found this statement :

正如其他成员已经回答的那样,它会产生未定义的行为。我想在这里提到的是,您从书中引用的(“在一台机器上”)似乎是片面的。它不会概括该行为。这本书可能还解释说,根据标准,行为是未定义的。顺便说一句,我刚刚浏览了“新 C 标准 - 经济和文化评论”并发现了以下声明:

The Intel Pentium SAL instruction (generated by both gcc and Microsoft C++ to evaluate left-shifts) only uses the bottom five bits of the shift amount

Intel Pentium SAL 指令(由 gcc 和 Microsoft C++ 生成以评估左移)仅使用移位量的底部五位

This very well explains why a left shift of -5 could result into a left shift of 27 ( for 2's complement representation of negative numbers )

这很好地解释了为什么左移 -5 会导致左移 27(对于负数的 2 的补码表示)

回答by Oliver Charlesworth

The behaviour is undefined.

行为未定义。

In 5-bit binary arithmetic, two's-complement -5 has the same binary representation as unsigned +27, which probably explains that particular platform.

在 5 位二进制算术中,补码 -5 与无符号 +27 具有相同的二进制表示,这可能解释了该特定平台。

回答by arnorhs

If the value you're shifting is a 32 bit variable, shifting -5 goes in a "loop" and shifts 27 forward. Shifting can only take place in a "unsigned" fashion.

如果您要移位的值是 32 位变量,则移位 -5 进入“循环”并向前移位 27。转移只能以“未签名”的方式进行。

回答by Wu Little

int main()
{
    unsigned int a = 1;
    printf("%u\n",a<<(-1));
    return 0;
}

The output is 2147483648.

输出为 2147483648。

Here is my assumption and validation:(just assumption!)

这是我的假设和验证:(只是假设!)

1.The "<<" right operand must be unsigned int type,

1.“<<”右操作数必须是unsigned int类型,

so firstly, the (int) “-1” will be cast into (unsigned int) "-1". Cause int type is two's-complement representation, the result will be 2^32-1(unsigned int)

所以首先,(int)“-1”将被转换为(unsigned int)“-1”。因为 int 类型是二进制补码表示,结果将是 2^32-1(unsigned int)

2.Due to number 2^32-1 is larger than the Max displacement digit, 2^32 - 1 will be mod 32, which equals 27

2.由于数字 2^32-1 大于最大位移位,2^32 - 1 将是 mod 32,等于 27

I also triedsome other nagetive right operand numbers, and the manual calculation results with assumpted rules will be the same with what product by my IDE.

还尝试了一些其他的负数右操作数,假设规则的手动计算结果与我的IDE的产品相同。

I am trying to find some supporting offical documents, witch could verificate whether my assumption is right or not. Maybe you can tell me.

我试图找到一些支持的官方文件,巫婆可以验证我的假设是否正确。也许你可以告诉我。