首页 > 解决方案 > 带前导 1 的位移

问题描述

当我在 C++ 中对 1000 使用 >> 位运算符时,它会给出以下结果:1100。我希望结果为 0100。当 1 位于任何其他位置时,这正是发生的情况,但是如果有前导 1,它就会出错。为什么会这样,如何避免?

标签: c++bitbit-shift

解决方案


您描述的行为与在某些平台上右移具有高位集的有符号整数(因此,负值)时发生的行为一致。

在这种情况下,在许多平台上,编译器会发出代码来执行算术移位,这会传播符号位;这一点,在负整数的 2 补码表示的平台上(= 几乎每个当前平台)即使在负值上也会产生“ x >> i= floor(x/2 i )”行为的效果。请注意,这不是合同规定的——就 C++ 标准而言,在实现定义的行为中移动负整数,因此任何编译器都可以自由地为其实现不同的语义1

要回答您的问题,要获得“常规”移位行为(通常称为“逻辑移位”),您必须确保使用unsigned整数。这可以通过确保您要移动的变量是无符号类型(例如unsigned int)来获得,或者,如果它是文字,则可以通过U为其添加后缀(例如1is an int, 1Uis an unsigned int)来获得。

如果您拥有的数据是有符号类型(例如int),您可以在无风险转移之前将其转换为相应的unsigned类型(从有符号 int 转换为无符号整数是由标准明确定义的,并且不会更改位2 的补码机器上的值)。


  1. 从历史上看,这是因为 C 努力支持甚至在硬件级别没有“廉价”算术移位功能和/或不使用 2 的补码表示的机器。

推荐阅读