我想弄清楚算术位移运算符在 C 中的工作原理,以及它将如何影响带符号的 32 位整数。
为简单起见,假设我们在一个字节(8 位)内工作:
x = 1101.0101
MSB[ 1101.0101 ]LSB
阅读 Stack Overflow 和一些网站上的其他帖子,我发现:
<<
将移向 MSB(在我的例子中是向左),并用 0 填充“空”LSB 位。
和>>
将向 LSB 移动(在我的例子中向右移动)并用 MS 位填充“空”位
所以,x = x << 7
将导致将 LSB 移动到 MSB,并将所有内容设置为 0。
1000.0000
现在,假设我会 >> 7
,最后的结果。这将导致 [0000.0010]
?我说得对吗?
我对轮类运算符的假设是否正确?
我刚刚在我的机器上测试过,**
int x = 1; //000000000......01
x = x << 31; //100000000......00
x = x >> 31; //111111111......11 (Everything is filled with 1s !!!!!)
为什么?
最佳答案
负符号数的右移具有实现定义的行为。
如果您的 8 位旨在表示一个带符号的 8 位值(因为您在切换到 8 位示例之前谈论的是“带符号的 32 位整数”),那么您有一个负数。将其右移可能会用原始 MSB 填充“空”位(即执行符号扩展)或者它可能会移入零,具体取决于平台和/或编译器。
(实现定义的行为意味着编译器会做一些明智的事情,但是以平台相关的方式;编译器文档应该告诉你什么。)
左移,如果数字一开始是负数,或者移位操作会将 1 移到或超出符号位,则具有未定义的行为(大多数对有符号值的操作都会导致溢出)。
(未定义的行为意味着任何事情都可能发生。)
unsigned 值的相同操作在这两种情况下都有明确定义:“空”位将填充 0。
关于c - 有符号整数的算术位移,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4009885/