c++ - 带前导 1 的位移
问题描述
当我在 C++ 中对 1000 使用 >> 位运算符时,它会给出以下结果:1100。我希望结果为 0100。当 1 位于任何其他位置时,这正是发生的情况,但是如果有前导 1,它就会出错。为什么会这样,如何避免?
解决方案
您描述的行为与在某些平台上右移具有高位集的有符号整数(因此,负值)时发生的行为一致。
在这种情况下,在许多平台上,编译器会发出代码来执行算术移位,这会传播符号位;这一点,在负整数的 2 补码表示的平台上(= 几乎每个当前平台)即使在负值上也会产生“ x >> i
= floor(x/2 i )”行为的效果。请注意,这不是合同规定的——就 C++ 标准而言,在实现定义的行为中移动负整数,因此任何编译器都可以自由地为其实现不同的语义1。
要回答您的问题,要获得“常规”移位行为(通常称为“逻辑移位”),您必须确保使用unsigned
整数。这可以通过确保您要移动的变量是无符号类型(例如unsigned int
)来获得,或者,如果它是文字,则可以通过U
为其添加后缀(例如1
is an int
, 1U
is an unsigned int
)来获得。
如果您拥有的数据是有符号类型(例如int
),您可以在无风险转移之前将其转换为相应的unsigned
类型(从有符号 int 转换为无符号整数是由标准明确定义的,并且不会更改位2 的补码机器上的值)。
- 从历史上看,这是因为 C 努力支持甚至在硬件级别没有“廉价”算术移位功能和/或不使用 2 的补码表示的机器。