我们都知道在计算机中所有的信息最终都是以二进制的0和1来表示,而有些算法是通过操作bit位来进行运算的,这就需要我们了解Python中如何去表示二进制,又如何是进行位运算的。

二进制的表示

首先在Python中可以通过以"0b"或者"-0b"开头的字符串来表示二进制,如下所示print 0b101 # 输出5print 0b10  # 输出2print 0b111 # 输出7print -0b101 # 输出-5

由此可知我们用二进制表示的数字在打印之后会变成我们更为熟悉的十进制数,更容易被人理解。

当我们需要看十进制数字的二进制表示时,可以使用bin函数bin(5)  # 输出0b101

二进制的位操作

首先一点需要明确的是所有的运算(包括位操作)在计算机内部都是通过补码形式来进行运算的,关于补码可以参考文章原码,反码和补码,计算机内部运算示意图如下:

image

在Python中提供了如下二进制的位操作:>>  #右移<

位运算法则:

image

下面我们分别来看下:

左移0b11 <

负数的左移相对来说就比较复杂,以-2 << 2为例,-2的原码是10000000000000000000000000000010(32位系统),其补码为11111111111111111111111111111110,左移之后变为11111111111111111111111111111000,再转化为原码即10000000000000000000000000001000,也就是-8,也就是-2*(2**2)=-8

左移超过32位或者64位(根据系统的不同)自动转化为long类型。

左移操作相当于乘以2**n,以5 << 3为例,相当于5(2*3),结果为40。

右移0b11 >> 1   #输出为1, 即0b15 >> 1      #输出为2,即0b10-8 >> 3     #输出为-1在Python中如果符号位为0,则右移后高位补0,如果符号位为1,则高位补1;

同样需要先转化为补码再进行计算,以-8 >> 3为例,-8的原码为10...01000,相应的补码为11...11000,右移后变为1...1,相应的原码为10...01,即-1。

右移操作相当于除以2**n,8 >> 3相当于8/(2**3)=1

或0b110 | 0b101   #输出7,即0b111-0b001 | 0b101  #输出-1

同样是转化为补码后再进行或运算, 只要有一位有1就为1。

所以或运算常常用于mask技术中的打开开关,即针对某一位把其置为1

比如将某个数字的第三位置为1,我们可以将mask设置为0b100,然后再或运算mask = 0b100

0b110000 | mask  #turn on bit 3

与0b110 & 0b011   #输出2,即0b010

与运算常常用于mask技术的关闭开关,即针对某一位把其置为0mask = 0b10

0b111111 & mask  #turn off bit 2

异或0b111 ^ 0b111   #输出00b100 ^ 0b111   #输出3

异或常用于将所有的位反转0b1010 ^ 0b1111  #输出5,即0b0101

非~0b101  #输出2,即0b010~-3     #输出2

非运算就是把0变1,1变0,唯一需要注意的是取非时符号位也会变换,比如-3,原码是10...011,补码是11...101,取非后变为00...010,由于符号位为0,所以对应的原码即为其本身,即2。

二进制工具

bitarray

关于bit有一个很有用的Packag叫做bitarray,其中bitarray对象可以帮助我们存储0,1值或者Boolean值,并像list一样进行操作。from bitarray import bitarray#初始化一个有10个bit位的数组,初始值为0a = bitarray(10)#可以像操作list一样操作bitarray对象a[1:8] = 1#bitarray还提供了一些特殊的方法,如:all()#当bitarray中所有的元素都为1时,all()返回为Trueif a.all():    print "all bits are True."

关于bitarrary的说明详见Github上的bitarray项目

位运算的应用

常见的应用如判断奇偶数 X & 0x1,变换符号位 ~X + 1,数字交换等,详细可以看参考链接中的文章

下面笔者想就实际项目中的一个例子来说明位操作的应用。

下表是一个TS Package header的说明(TS流是流媒体行业常用的传输格式),我们看到为了减少不必要的浪费,包头在定义域的时候都是按位进行定义的,那么我们如果想要取相应的域的值,也就需要使用位操作了。

Packet Header(包头)信息说明

| 序号 | 名称 |bit数|说明|

|---|---|---|---|---|

|1 | sync_byte | 8bits | 同步字节|

|2 | transport_error_indicator | 1bit | 错误指示信息(1:该包至少有1bits传输错误)|

|3 | payload_unit_start_indicator | 1bit | 负载单元开始标志(packet不满188字节时需填充)|

|4 | transport_priority | 1bit | 传输优先级标志(1:优先级高)|

|5 | PID | 13bits | Packet ID号码,唯一的号码对应不同的包|

|6 | transport_scrambling_control | 2bits | 加密标志(00:未加密;其他表示已加密)|

|7 | adaptation_field_control | 2bits | 附加区域控制|

|8 | continuity_counter | 4bits | 包递增计数器|

我们以取PID值为例,当我们获取到包头的字节串之后,我们需要如下几个步骤:需要取到第2个字节,然后忽略第二个字节的高三位(从表中可以看出高三位为其它信息与PID无关);

将第二个字节的后5位数字左移8位,这样将其移到高位;

移位后与第3个字节的数值相加得到PID的值。

要实现第一步,首先就要用到位操作中常用的mask技术,即通过将对应位为0的数值进行&操作0b10110111 & 0b00011111 #将高位的3位进行mask关闭操作,使得其值被去除

要实现第二步,就需要用到左移操作,左移操作之后与第三个字节的数值相加就是实际的PID值

完整代码实现如下:def get_package_pid(package):

if package is None:        raise Exception("get_package_pid param package is None.")    return ((ord(package[1]) & 0x1f) <

注:

1, ord()将byte串转化为对应的数字从而进行位运算;

2, 0x1f是十六进制表示,转化为二进制就是0b00011111.

参考链接:

作者:geekpy

链接:https://www.jianshu.com/p/3a31065a8e58

python中二进制以什么开头_Python二进制表示和位操作相关推荐

  1. python十进制小数转二进制_在python中如何将十进制小数转换成二进制

    在python中如何将十进制小数转换成二进制 在最近的学习中发现博客园里面找不到如何在python中如何将十进制小数转换成二进制,所以我用土方法写了一个超级简单的转换方法(不过转换出来的数只是形式上是 ...

  2. python语言单行注释以什么开头_python中单行注释以什么开头

    学会向程序中添加必要的注释,也是很重要的.注释不仅可以用来解释程序某些部分的作用和功能(用自然语言描述代码的功能),在必要时,还可以将代码临时移除,是调试程序的好帮手. 当然,添加注释的最大作用还是提 ...

  3. [转载] python中for语句用法_详解Python中for循环的使用_python

    参考链接: 在Python中将else条件语句与for循环一起使用 这篇文章主要介绍了Python中for循环的使用,来自于IBM官方网站技术文档,需要的朋友可以参考下 for 循环 本系列前面 &q ...

  4. python中for语句用法_详解Python中for循环的使用_python

    这篇文章主要介绍了Python中for循环的使用,来自于IBM官方网站技术文档,需要的朋友可以参考下 for 循环 本系列前面 "探索 Python,第 5 部分:用 Python 编程&q ...

  5. python中哪些是注释符号_Python注释用什么符号

    Python是一种计算机程序设计语言.是一种面向对象的动态类型语言,最初被设计用于编写自动化脚本(shell),随着版本的不断更新和语言新功能的添加,越来越多被用于独立的.大型项目的开发. Pytho ...

  6. python中异或怎么算_python 异或运算的前提_异或运算公式

    Python基础(10)–数字-Python-第七城市 609x288 - 73KB - JPEG Python基础(10)--数字_资讯_突袭网 609x288 - 33KB - JPEG pyth ...

  7. python整数类型进制表示_Python二进制、八进制、十六进制数字的表示和转换

    除了常用的十进制表示法,Python 也支持二进制.八进制和十六进制表示法.这些只是表示方法不同,但是它们表示的含义是一样的,如二进制中的 11 和十进制数中的 3 是一样的. 1. Python 二 ...

  8. python的单行注释以什么开头_python中单行注释以什么开头,

    详细内容 学会向程序中添加必要的注释,也是很重要的.注释不仅可以用来解释程序某些部分的作用和功能(用自然语言描述代码的功能),在必要时,还可以将代码临时移除,是调试程序的好帮手. 当然,添加注释的最大 ...

  9. python中find函数忽略大小写_python字符串(大小写、判断、查找、分割、拼接、裁剪、替换、格式化)...

    一.通用操作 1.Python len() 方法返回对象(字符.列表.元组等)长度或项目个数. 语法 len()方法语法: len( q ) 参数 q -- 对象. 返回值 返回对象长度. 实例 以下 ...

最新文章

  1. Oracle 11g 内存结构
  2. 【Dart学习】-- Dart之泛型
  3. 拯救你的颈椎,笔记本支架如何选择?
  4. 大数据之-Hadoop完全分布式_Crondtab定时任务调度---大数据之hadoop工作笔记0042
  5. 中国AI公司公开击败谷歌微软,这次是Yi+AI视觉团队
  6. Eclipse 反编译之 JadClipse
  7. Java之美[从菜鸟到高手演变]之设计模式二
  8. InputMethodManager内存泄漏的原因及解决方案
  9. “非常晚餐”第一期 “3D虚拟世界”是“黑客帝国”吗?
  10. 3D建模操作详细步骤
  11. 利用强化学习设计具有目标有效杨氏模量的复合材料
  12. 项目组自己编写的js分页标签(百度分页)
  13. TICA 2019 基于人工智能的模型驱动测试设计
  14. 【AHK】在Obsidian中以选定日期生成链接
  15. 保险机构如何保护客户信息安全?
  16. Vue elementUI-select多选下拉框数据回显成功后,点击下拉选项或删除回显数据无反应...
  17. AssemblyBuilder以及Activator双剑合璧
  18. 前端websocket的一些属性,以及websocket的断开重连
  19. 购买计算机配置总结,买电脑主要看什么 教你怎么看电脑配置信息
  20. 时间戳与时间的转换大全

热门文章

  1. Peer J:整合高通量绝对丰度定量方法解析土壤细菌群落及动态
  2. 如何开启win10内置Linux子程序
  3. pandas使用rename函数重命名dataframe中数据列的名称、从而创建一个包含重复列名称的dataframe数据集
  4. pandas创建复合索引dataframe仿真数据集实战(create a multiIndex dataframe)
  5. R语言使用upper.tri函数、lower.tri函数、diag函数改变matrix矩阵上三角形、下三角形、对角线的数值
  6. R语言可视化包ggplot2包通过因子变量设置图像颜色实战
  7. R语言Gamma分布函数Gamma Distribution(dgamma, pgamma, qgamma rgamma)实战
  8. Plotly可视化输出数据表格(table):简单表格、添加链接的表格
  9. 关联规则概念、啤酒加尿布引出购物篮分析、频繁项集、支持度+置信度+提升度
  10. 影像组学视频学习笔记(12)-支持向量机(SVM)参数优化(代码)、Li‘s have a solution and plan.