Python左移 << 和右移 >>
困难4二进制“推拉”术:左移<<和右移>>,让计算飞起来
你有没有想过,计算机里做乘除运算其实有一种“作弊”般的神速方法?没错,就是位运算中的左移(<<)和右移(>>)。它们像在数字的二进制队形上“推”或“拉”位置,几毫秒就能算出乘以2、除以2的结果。今天我们就来揭开它们的神秘面纱,你会发现它们其实和生活里的“排队加零”、“切掉末尾”一模一样。
先说说二进制——数字的“暗号”
我们平时用十进制(0~9),但计算机只懂二进制(0和1)。比如数字5,在二进制里是 101(因为1×4 + 0×2 + 1×1 = 5)。左移和右移就是在这个二进制串上做手脚,就像你在纸上写数字,然后在后面加零或者去掉末尾。
1. 左移 << —— 在二进制数后面“加零”
含义: 左移 n 位,就是在二进制数的末尾添加 n 个 0。效果相当于原数乘以 2 的 n 次方。
举个例子:
- 数字3(二进制
11),左移2位,变成1100(也就是在11后面加了两个0)。 - 二进制
1100换算成十进制:1×8 + 1×4 + 0×2 + 0×1 = 12。 - 果然,3 × 2² = 3 × 4 = 12。
生活中的类比:
你手里有3颗糖,老师奖励你“每颗糖乘以4倍”,你一共得到12颗糖。左移2位就是这种“翻倍再翻倍”的感觉。
另一个例子:
5 << 1,5的二进制是101,左移1位变成1010(十进制10)。这等于5×2=10。
如果左移3位呢?5 << 3 → 101000(十进制40),就是5×2³=5×8=40。
代码试试:
# 左移示例
num = 5 # 二进制 101
print("5 << 1 =", num << 1) # 输出 10,因为 5*2=10
print("5 << 2 =", num << 2) # 输出 20,因为 5*4=20
print("5 << 3 =", num << 3) # 输出 40,因为 5*8=40
2. 右移 >> —— 把二进制数末尾的数字“丢掉”
含义: 右移 n 位,就是去掉二进制数最右边的 n 个位(不够就变成0)。效果相当于原数除以 2 的 n 次方,并向下取整(对正数就是整除)。
举个例子:
- 数字12(二进制
1100),右移2位:去掉最右边2个位,剩下11(二进制),也就是3。 - 12 ÷ 4 = 3,完全吻合。
生活中的类比:
你和朋友一共有12块饼干,要平均分成4份,每份正好3块。右移2位就是“除以4并取整”。
另一个例子:
5 >> 1,5的二进制101,右移1位:丢掉最右边的1,剩下10(二进制),即2。
5 ÷ 2 = 2.5,向下取整得2。注意:这里并没有四舍五入,而是直接砍掉小数部分。
注意: 对于正数,右移就是整除;对于负数,Python的处理会有点不同(向下取整更严格),我们暂时只讨论正数,大家别慌。
代码试试:
# 右移示例
num = 12 # 二进制 1100
print("12 >> 2 =", num >> 2) # 输出 3,因为 12//4=3
print("12 >> 1 =", num >> 1) # 输出 6,因为 12//2=6
num2 = 7 # 二进制 111
print("7 >> 1 =", num2 >> 1) # 输出 3,因为 7//2=3(舍去0.5)
3. 为什么说左移右移“速度快”?—— 因为计算机天生爱二进制
普通乘法(比如 3 * 4)在底层其实也是通过加法循环完成的,步骤较多。而左移右移是直接修改二进制位,CPU只需一步搞定。所以当你需要计算 乘以或除以 2 的 n 次方 时,用移位代码会跑得飞快。尤其在游戏、图形处理、加密算法里,程序员经常用移位代替乘除。
举例:
x * 16可以写成x << 4(因为16=2⁴)y // 8可以写成y >> 3(因为8=2³)
但是要注意:只能用于2的幂,比如乘以10就不能直接用移位(但可以组合:x*10 = x*8 + x*2 = (x<<3) + (x<<1))。
4. 新手最容易犯的3个错误
错误1:以为左移会改变原变量的值
a = 5
a << 1 # 这一行只是计算了结果,没有赋值给a
print(a) # 还是5,不是10!
正确做法:必须把结果赋值给变量,比如 a = a << 1 或 a <<= 1(简写形式)。
错误2:对负数右移的理解偏差
对于正数,右移就是整除;但对于负数(如 -5 >> 1),Python会执行“向下取整”的除法(向负无穷方向),结果是-3(因为-5/2=-2.5,向下取整是-3)。这和数学上“负数的整除”略有不同。建议初学者先只用在正数上。
错误3:左移位数太大导致溢出(虽然Python不会)
有些语言(如C语言)中,左移超过整数位数会导致数据丢失,但Python的整数可以无限大,所以没问题。不过要注意效率:左移太多位会创建一个非常大的整数,占用内存。
5. 完整可运行示例——用零花钱来计算
假设你每周有零花钱 money 元,妈妈决定翻倍(乘以2)给你,你会用左移吗?爸爸说要把你的钱分给4个兄弟(除以4),你会用右移吗?写个程序看看:
# 完整示例:零花钱与移位
money = 10 # 每周零花钱10元
print("原来每周有", money, "元")
# 妈妈翻倍:乘以2
double_money = money << 1 # 10 * 2 = 20
print("妈妈翻倍后:", double_money, "元")
# 爸爸要分给4个兄弟:除以4
share = money >> 2 # 10 // 4 = 2(每个人只能拿2元,因为10/4=2.5取整)
print("分给4个兄弟每人:", share, "元")
# 如果爸爸改成分给2个兄弟:除以2
share2 = money >> 1 # 10 // 2 = 5
print("分给2个兄弟每人:", share2, "元")
# 验证左移是否等于乘以2的幂
print("验证:money << 3 =", money << 3, " money * 8 =", money * 8) # 都等于80
运行结果:
原来每周有 10 元
妈妈翻倍后: 20 元
分给4个兄弟每人: 2 元
分给2个兄弟每人: 5 元
验证:money << 3 = 80 money * 8 = 80
6. 相关指引——学完这个,你还可以继续了解
- 与运算 & 和 或运算 |:位运算的另外两个好伙伴,可以帮你检查某个位是0还是1。
- 按位异或 ^:同一个数字异或两次会变回原数,常用于简单的加密。
- 补码与负数移位:如果想深入了解负数在二进制里的表示,可以搜索“补码”和“算术右移”。
- 位运算的实战用途:设置游戏角色的状态(比如是否隐身、是否无敌),常用位运算来记录多个开关。
左移右移就像编程世界的“快捷键”,学会了它们,你的代码不仅更快,还更酷。赶紧打开Python试试吧!
例题精讲
在Python中,表达式 3 << 2 的结果是多少?
在Python中,-5 >> 1 的结果是多少?
在Python中,-8 >> 2 的结果是 -2。
在Python中,1 << 100 的结果是 2^100 且不会溢出。
请在横线处填入正确代码,使得输出结果为36:
print((8 << 2) + ___)