猿问

有符号整数上的算术位移位

有符号整数上的算术位移位

我试图弄清楚算术位移位运算符在C中是如何工作的,以及它将如何影响带符号的32位整数。

为了简单起见,假设我们在一个字节(8位)内工作:

x = 1101.0101MSB[ 1101.0101 ]LSB

阅读Stack Flow和一些网站上的其他帖子,我发现:<<将转向MSB(在我的例子中,向左),并用0填充“空”LSB位。

>>将转向LSB(在我的例子中,向右),并用MS位填充“空”位

所以,x = x << 7将导致将LSB移动到MSB,并将所有设置为0。

1000.0000

现在,假设我>> 7,最后的结果。这将导致[0000.0010]?我说的对吗?

我对轮班操作员的假设是对的吗?

我刚在我的机器上测试了*

int x = 1;   //000000000......01x = x << 31; //100000000......00x = x >> 31; //111111111......11 (Everything is filled with 1s !!!!!)

为什么?


饮歌长啸
浏览 646回答 3
3回答

慕盖茨4494581

负号数字的右移具有实现定义的行为.如果您的8位表示有符号的8位值(在切换到8位示例之前,您指的是“带符号的32位整数”),那么您就有了一个负数。向右移动可能会用原始的MSB(即执行符号扩展)填充“空”位,或者根据平台和/或编译器的不同,将其移动为零。(实现定义的行为意味着编译器将以一种依赖于平台的方式做一些明智的事情;编译器文档应该告诉您什么。)如果数字开始为负值,或者移位操作会将1移到或超过符号位,则左移位具有未定义的行为(与大多数对有符号值的操作一样,这些操作都会导致溢出)。(未定义的行为意味着任何事情都可能发生。)相同的操作未签名在这两种情况下都很好地定义了值:“空”位将用0填充。

森栏

正如其他人所说,负价值的转移是由实现定义的。大多数实现将签名的右移位作为层(x/2)。N)通过使用符号位填充移位的位。这是非常方便的实践,因为这是如此普遍的操作。另一方面,如果你要右移无符号整数,移位的位将被归零。从机器端看,大多数实现有两种类型的右移指令:一种“算术”右移(通常有助记符ASR或SRA),就像我解释的那样。一种“逻辑”右移(通常具有助记符LSR或SRL或SR),如您所期望的那样工作。大多数编译器使用第一个用于符号类型,第二个用于无符号类型。只是为了方便。
随时随地看视频慕课网APP
我要回答