算法通关村 —— 移位运算解析

目录

算法通关村 —— 移位运算解析

1. 计算机中的数字

2 移位运算

3 移位运算与乘除法的关系


算法通关村 —— 移位运算解析

1. 计算机中的数字

在进行移位运算的学习前,我们先了解下数字在计算机中的表示。

机器数:数字在计算机中以二进制的形式表示,叫做这个数的机器数。机器数带符号,计算机中最高位的数存放符号,正数为0,负数为1。比如,十进制的+5,计算机字长为8位,转换成二进制就是00000101。如果是-3,就是10000101。

真值: 由于机器数第一位是符号,为了区分机器数与真正的数值,将带符号位的机器数对应的真正数值称为机器数的真值。例:00000010真值为2,10000010真值为-1。

原码: 就是符号位加上真值的绝对值,即用第一位表示符号,其余位表示值。例:

[ +1 ] 原 = 00000001   [ -1 ] 原 = 10000001

第一位为符号位,所以8位2进制数取值范围为[ 11111111, 01111111], 即 [-127, 127]。

反码:正数的反码是其本身,负数的反码是在原码基础上,符号位不变,其余位取反。

例:[ +1 ] = [ 00000001 ] 原 = [ 00000001 ] 反             [ -1 ] = [ 10000001 ] 原 = [ 11111110 ] 反

补码:正数的补码是其本身,负数的补码是在其原码的基础上,符号位不变,其余各位取反,最后+1。

例:  [ +1 ] = [ 00000001 ] 原 = [ 00000001 ] 反  =  [ 00000001 ] 补        

         [ -1 ] = [ 10000001 ] 原 = [ 11111110 ] 反 = [ 11111111 ] 补        

2 移位运算

移位运算其实就是类似将原始数字除以2或者乘以2的运算,具体计算形式可能有所不同。

按照 移位方向 可以分成 左移 和 右移

按照 是否带符号 可以分成 算术移位 和 逻辑移位

算术移位:用高位补最高位

逻辑移位:  高位补0

左移运算:符号是 <<, 将全部二进制位向左移动若干位,高位丢弃,低位补0。对于左移运算,算术移位和逻辑移位相同。

右移运算:符号是 >>, 将全部二进制位向右移动若干位,低位丢弃,高位的补位由算术移位或逻辑移位决定: 算术移位时,高位补最高位;逻辑移位时,高位补0.

示例:
1)29的二进制表示为00011101,29左移2位后二进制表示为01110100,结果为116

2)50的二进制表示为00110010,50右移2位后二进制表示位00001100,结果为12,由于正数或0的第一位都位0,所以对于0和正数,无论是算术右移还是逻辑右移,其高位都是补0,所以两者右移的结果是相同的

3)-50的二进制表示为10110010,补码为11001110,-50算术右移两位后二进制表示为 11110011,对应的二进制原码为10001101,即为-13;-50逻辑右移2位二进制表示为00110011,正数的补码是其本身,故原码同为00110011,即为51

所以右移运算中算术移位和逻辑移位是不同的,计算机内部的右移运算采取哪一种呢?

⚪ 对于C/C++, 数据类型包含有符号类型和无符号类型,分别用关键字signed和unsigned声明。不使用关键字时默认为有符号类型。对于有符号类型,右移运算为算术右移,对于无符号运算,右移运算为逻辑右移。

⚪ 对于Java,不存在无符号类型,所有的表示整数的类型都是有符号类型,因此需要区分算术右移和逻辑右移。在Java中,算术右移符号是 >>, 逻辑右移符号是 >>>。

3 移位运算与乘除法的关系

由上可知,移位运算就是令指定数乘或除以2的若干次幂,所以通过移位运算可以实现乘除操作。由于计算机底层的一切运算都是基于位运算实现的,因此使用移位运算实现乘除法的效率高于直接乘除法。

左移运算对应乘法运算。将一个数左移k位,等价于将该数乘以2^k。例如,29左移两位结果为116,等价于29 × 4。而当乘数不是2的整数次幂时,则可以将乘数拆成若干项2的整数次幂之和,例如: a × 6 等价于a × (4 + 2), 即(a<<2)+(a<<1)。所以对任意整数,乘法运算都可以用左移运算实现,但需注意溢出的情况,例如在8位二进制表示下,29左移3位就会出现溢出。

算术右移运算对应除法运算。将一个数右移k位,相当于将这个数除以2^k。例如,50右移2位结果为12,等价于50 / 4,结果向下取整。

注意:对于0和整数,可以说将一个数算术右移k位和将这个数除以2^k等价,因为整数除法是向0取整,右移运算是向下取整,也是向0取整。但是对于负数,就不成立了,整数除法是向0取整,而右移运算是向下取整,但注意此时为负数向下取整,所以两者就不同了。例如(-50)>> 2 结果是-13, 而(-50)/ 4 结果是-12,两者不相等。但是不用担心,算法出题早就考虑了这一点,所以大部分算法题都将测试数据限制在正数和0的情况,因此可以放心地左移或者右移。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值