python中有一种位运算——算术位移运算,符号是<<或>>,算术位运算是基于补码的基础上进行的,正数的补码是正数本身,而负数的补码就比较复杂,先把写出正数的二进制,然后取反,再末尾加1。总而言之,不管是什么进制的数先把它转换成二进制,然后再进行位移。先来一段代码。

# 左移(补0)           m<<n ---> m*2的n次方
# 右移(补位看符号位)   m>>n ---> m//2的n次方  
print(2<<1)   #4

print(2>>1)   #1

来一个具体计算的示意图:

python numpyt 左移 python中的左移位_补码


左移:先把二进制写出来,现在的计算机都是什么32位,64位啥的,不嫌多的话写上32位的二进制,不想写那么多的就写个8位的二进制。想像一下,在这个二进制前面有一个黑洞,左移就是把这个二进制一位一位的往左边那个黑洞推,推进去的那一位就被吃了,这就导致位数不够了,我们就在这个二进制的右端补0呗,被吃了几位就补几位。

右移:和左移类似只不过黑洞就在了右边,往右推二进制,在二进制的左边补位,补什么呢,这就看这个数的符号位(第一位)了。

举个简单的栗子:

python numpyt 左移 python中的左移位_python numpyt 左移_02


我们要记住的是!!!:在数字没有溢出的前提下,对于正数和负数,左移以为都相当于乘以2的1次方,左移n位就相当于乘以2的n次方;右移一位相当于除以2,右移n位相当于除以2的n次方,这里取的是商,不要余数。正数右移的最小结果是0,负数右移最小是-1

这个时候我们就来练习一下:

1.64<<2 =?
 把64转换成二进制0000 0000 0000 0000 0000 0000 0100 0000
 左移就是左边少两位,右端多两个0。就变成了
 0000 0000 0000 0000 0000 0001 0000 0000 转换成十进制就是256
 是不是等于6422呢?
 2.-64<<2
 碰到负数我们先把负数转换成它的二进制的补码,-64的二进制补码就是
 1111 1111 1111 1111 1111 1111 1100 0000 之后就是左边少两位,右端多两个0,就变成了1111 1111 1111 1111 1111 1111 0000 0000 这个就是结果的二进制补码,我们再把他转成10进制的,怎么转呢?先看首位是1,就知道这是个负数。然后末尾减1,得1111 1111 1111 1111 1111 1110 1111 1111 再取反得
 0000 0000 0000 0000 0000 0001 0000 0000 这个数是多少呢?这不就是256嘛,再加上负号,结果就是-256。
 3.-64>>2
 -64的二进制补码怎么得到的呢?64的二进制
 0000 0000 0000 0000 0000 0000 0100 0000 取反得
 1111 1111 1111 1111 1111 1111 1011 1111 再末尾加1得
 1111 1111 1111 1111 1111 1111 1100 0000 这就是-64的二进制补码。
 右移就是往右推二进制,在二进制的左边补位,那么得到的是
 1111 1111 1111 1111 1111 1111 1111 0000 这个就是结果的二进制补码,接下来转成10进制,首位是1那么就是个负数,然后末尾取减1得
 1111 1111 1111 1111 1111 1111 1110 1111 然后取反得
 0000 0000 0000 0000 0000 0000 0001 0000 这个数是多少呢?结果就是-16。