算术移位和逻辑移位

算术移位和逻辑移位:

unsigned int i = 8;

int main(){

i = i<<3;//输出结果i = 64

}

上面的变量i是采用逻辑移位还是算术移位呢?

逻辑移位,简单理解就是物理上按位进行的左右移动,两头用0进行补充,不关心数值的符号问题

算术移位,同样也是物理上按位进行的左右移动,两头用0进行补充,但必须确保符号位不改变

但我们好奇的是“i<<3”和“i>>3”到底采用的是算术还是逻辑移位呢?其实单从C语言本身来看可能没有太多突破,因为C最终会被编译器编译成目标平台的汇编代码,所以必须要结合编译器和汇编程序来分析以上代码,下面主要从反汇编入手分析,对ARM平台下有关移位的指令有:

LSL(逻辑左移)

LSR(逻辑右移)

ROR(循环右移)

ASL(算术左移)

ASR(算术右移)

RRX(带扩展的循环右移)



下面我们来看看上面那段C程序的反汇编结果:




结论:说明无符号数采用的是逻辑左移。

那么经过测试我们发现以下几份代码反汇编结果和上面的情况是一样的,都是逻辑左移:

signed int i = 8;

int main()

{

i = i<<3;//输出结果i = 64

}

signed int i = -8;

int main()

{

i = i<<3;//输出结果i = -64

}

结论:说明不管是否有无符号类型,也不管值的正负,均采用的是逻辑左移。

接下来看看右移:

unsigned int i = 8;

int main()

{

i = i>>3;//输出结果i = 1

}

反汇编结果:




结论:说明无符号数采用的是逻辑右移。

再看看有符号数的右移操作:

signed int i = 8;

int main()

{

i = i>>3;//输出结果i = 1

}

反汇编结果:



结论:说明有符号数采用的是算术右移。

经过测试发现以下代码反汇编结果和上面的情况也是一样的:

signed int i = -8;

int main()

{

i = i>>3;//输出结果i = -1

}

结论:说明只要是有符号数,不管值是正还是负,右移时采用的都是算术右移。

疑问:按照移位补0的原则,为何左移都是逻辑移位呢?

答疑:先看看“-8”和“8”在计算机内存中的值分别是:

0xfffffff8

0x8

由于计算机均按补码保存数值,所以不管符号正负,左移对于符号位并不产生影响,而右移则就不同了,无符号数怎么右移都不影响符号位,但是有符号数逻辑右移时高位补0将改变符号位,所以只能采用算术右移。

总结:只有有符号数右移才采用算术右移,否则其它情况都采用逻辑移位操作(逻辑左移或逻辑右移)。原来只要明白计算机是以补码方式保存数值的,就一切都清楚了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
算术移位逻辑移位都是计算机中常见的移位操作,它们的区别主要在于处理有符号数时的不同。 逻辑移位是指将二进制数按照指定的位数进行移动,空出的位用0填充,不考虑数值的正负。逻辑移位可以分为左移和右移两种情况: 1. 左移:左移是指将二进制数向左移动n位,空出的n位用0填充,相当于将数值乘以2的n次方。 2. 右移:右移是指将二进制数向右移动n位,空出的n位用0填充,相当于将数值除以2的n次方。 算术移位是指在逻辑移位的基础上,对于有符号数,需要保留符号位,即最高位不填充0,而是填充符号位。算术移位也可以分为左移和右移两种情况: 1. 左移:左移是指将二进制数向左移动n位,空出的n位用0填充,不过最高位的符号位要保留。 2. 右移:右移是指将二进制数向右移动n位,空出的n位用0填充,不过最高位的符号位要保留。 算术移位逻辑移位的区别在于,在算术移位中,右移操作会保留符号位,而左移操作不会导致符号位的变化。因此,对于有符号数而言,算术移位可以保持数值的正负不变,而逻辑移位则会改变数值的正负。 例如,对于二进制数1010,左移一位后得到的结果是0100,右移一位后得到的结果是1101。但是,如果将1010看作有符号数-6(最高位为符号位),左移一位后得到的结果是0100,相当于将-6乘以2,结果为-12;右移一位后得到的结果是1101,相当于将-6除以2,结果为-3。 综上所述,算术移位逻辑移位的区别主要在于处理有符号数时是否保留符号位。在实际应用中,需要根据具体的需求和场合选择适当的移位操作,以便实现正确的数值计算和处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值