如果对应于有符号整数的位模式向右移动
1 vacant bit will be filled by the sign bit 2 vacant bit will be filled by 0 3 The outcome is implementation dependent 4 none of the above
这个问题的答案是第三种选择..任何人都能解释一下这个问题,
还给出了一些基本思想,关于C编程中左移和右移算子背后的理论.例如
当执行任何操作时,空位上填充的内容.我检查并注意到左移将空位填充0并且右移填充1.请清除逻辑...
C不保证有符号位,或者有关整数的位级表示的任何信息,这就是原因.
对于二进制补码,您通常会看到符号位被移入,但这取决于实现.
我必须检查规范,了解具体依赖于实现的问题.但是,我在(mumble)多年的嵌入式系统项目中使用的每个实现都是明智的:
左移位总是在低位移位0.没有其他价值是有道理的.
右移取决于数据类型.有符号整数的右移将高位移位,因为它将其余的移位到右侧.这被称为"算术移位",并且具有良好的属性(至少在二进制补码算法中),它将值除以2,同时保留原始数字的符号.
无符号整数的右移将0移位到高位,通常称为"逻辑移位".
实现提供两种移位是有意义的,因为它们都很有用,并且使用signed/unsigned来选择哪个是合理的选择.
编辑:至少有一件绝对是依赖于实现的事情是C标准没有(完全)指定整数及其存储的底层实现.例如,可以为使用一个补码算法的机器构建一个兼容的C编译器.(我认为)也可以为一台机器构建一个兼容的编译器,该机器的本机存储器是标记为BCD的.(不,我错了,见下文.)
在实践中,世界几乎已经确定了CPU的两个补码二进制,并且一些迂腐的人被提出来.
所以问题的一部分实际上是:无论使用何种基础算术系统,如何以稳定的方式定义<<和>>运算符的含义.
IIRC,定义n<<1
是有效的n*2
,并且n>>1
实际上n/2
是自然延伸超过1(但不超过31 ......那里有未定义的龙......)以及>>
运营商将保留的概念如果在签名值上运行,则签名.
编辑2: Pete Kirkham在他的回答中指出,C标准确实特别禁止BCD表示整数的可怕情况,无论是有符号大小还是十进制补码.我确信这是一件好事,即使Knuth在早期版本的"计算机编程艺术"中使用了(可选的)BCD机器作为他的示例代码.
在那些BCD是正确答案的罕见用例中,然后将它们存储在无符号长(8位十进制补码)或无符号64位整数(16位十进制补码或15位加号和标志的空间)中并使用精心设计的算术库来操纵它们是有道理的.
当然,在实践中,C实现将操作符直接映射到标准允许的CPU本机指令.编写标准的人非常注意存在许多方法来实现甚至简单的事情,例如积分值的表示,而C标准反映了通过允许足够的实现定义的行为来让运算符在每个中有效地实现机.
替代方案迅速进入一个完全指定所有数学运算的世界,并且无法在任何机器上有效实施.