Python | 数的进制及其位运算

本文总结如何对数字进行进制转换和位运算及其应用。

Last Modified: 2023 / 8 / 19

Python | 数的二进制与位运算

  • 进制
    • 二进制
    • 十六进制
  • 转换
    • 数据类型
      • 数字
        • int
          • 方法
          • 示例
        • eval
          • 方法
          • 示例
      • 字符串
    • 进制
      • 原始输出
      • 标准输出
    • 原码、反码、补码
      • 概念
      • 转换
  • 位运算
    • 运算符
      • 按位与运算符 ```&```
      • 按位或运算符 ```|```
      • 按位异或运算符 ```^```
      • 按位取反运算符 ```~ ```
      • 左移动运算符 ```<<```
      • 右移动运算符 ```>>```
    • 应用
      • 按位与运算符 &
        • 清零
        • 提取指定位数
        • 保留最后一个1
        • 判断奇偶性
      • 按位或运算符 |
        • 使指定位数置1
      • 按位异或运算符 ```^```
        • 翻转指定位数
        • 保留原值
        • 交换a和b
      • 按位取反运算符 ```~ ```
        • 使最后一位置0
      • 左移动运算符 ```<<```
      • 右移动运算符 ```>>```
    • 总结
  • 参考链接
    • 进制
      • 二进制
      • 十六进制
    • 转换
    • 位运算


进制

对于任何一个数,我们可以用不同的进位制来表示。比如:十进数57(10),可以用二进制表示为11001(2),也可以用五进制表示为212(5),也可以用八进制表示为71(8)、用十六进制表示为39(16),它们所代表的数值都是一一样的。

二进制

计算机将各种信息存储为称为位的二进制数字流。无论您是处理文本、图像还是视频,它们都归结为 1 和 0。

Python 的按位运算符让您可以在最细粒度的级别上操作这些单独的数据位。您可以使用按位运算符来实现压缩、加密和错误检测等算法,以及控制Raspberry Pi 项目或其他地方的物理设备。通常,Python 将您与具有高级抽象的底层位隔离开来。在实践中,您更有可能发现按位运算符的重载风格。

十六进制

十六进制是计算机中数据的一种表示方法。它的规则是“逢十六进一”。

1个字节是

8位二进制数:

二进制8位:xxxxxxxx ,范围:00000000-11111111,表示0到255。

2位十六进制数:

一位16进制数(0-F),用二进制表示是xxxx,范围:0000 - 1111,表示:0到16。
16进制要表示1个字节,需要到255,此时就还需要第二位,0x3E。
所以1个字节=2个16进制字符,一个16进制位=0.5个字节。


转换

python内部以十进制进行运算,即二进制,八进制,十六进制,全是str 类型,而十进制为 Int 类型。
在某些情况下,需要被处理的原始数据也未必是二进制,则此时需要进制转换,比如二进制数字0b110000000000011101001111000100, 等同于八进制数字0o6000351704,等同于十进制数字805426116, 等同于十六进制0x3001d3c4

数据类型

数字

给定的数据类型可能为字符串类型,此时需要做转换以将其转换为便于计算的数字类型,即 字符串 -> 数字


int
方法
  • int(str)
  • int(str, 8)
  • int(str, 16)

但是没有```int(str, 2)


示例
int(12)
# 12

int('12', 16)
# 18
# 等同于将十六进制的 `0x12` 转换为十进制的 `18`

eval

eval() 函数用来执行一个字符串表达式,并返回表达式的值 1

以下是 eval() 方法的语法:

eval(expression[, globals[, locals]])
参数 描述
expression 表达式。
globals 变量作用域,全局命名空间,如果被提供,则必须是一个字典对象。
locals 变量作用域,局部命名空间,如果被提供,可以是任何映射对象。
方法
  • eval(f"{str:b}")
  • eval(f"{str:o}")
  • eval(f"{str:d}")
  • eval(f"{str:x}")

示例
eval(f"{2:b}")
# 10
# int

eval(f"{10:o}")
# 12
# int

eval(f"{17:x}")
# 11
# int

字符串

在某些情境下可能需要输出字符串类型的数据。为什么没有16进制int转化为string,可以这么认为不管什么进制,python在内部表示都是10进制,先转化为10进制在进行。如16进制int转化为string,str(0x12),首先变为str(18),再到18。那么我想结果为’12’,怎么办?这其实就是10进制int转化为string,即hex(0x12)

  • 数字 --> 字符串
    bin()
    oct()
    str()
    hex()

比如:

str(12)
>12
hex(18)
>0x12                    等同于将十进制18转换为十六进制的0x12


进制

原始输出

  • X进制 --> 二进制
    bin()
  • X进制 --> 八进制
    oct()
  • X进制 --> 十进制
    int()
    int(str, X)
  • X进制 --> 十六进制
    hex()

比如:

int(0x3001d3c4)
>805426116
int('0x3001d3c4', 16)
>805426116


标准输出

  • 仅数字
    bin().replace('0b', '')
    oct().replace('0o', '')
    hex().replace('0x', '')
  • 固定输出位数
    '{:010b/o/x}'.format()

比如'{:032b}'.format(0x3001d3c4)


原码、反码、补码

概念

  • 原码
    存在于人的大脑里。
    是二进制的原始表示法。
  • 反码
    存在于人的大脑里。
    二进制码0变1,1变0叫做反码。
    反码用于原码补码之间的转换
  • 补码。
    在电脑中物理存在的只有补码。
    用来做数据的存储运算,可以实现计算机底层的减法操作,因而提出(可以表达出一个数的正负),也就是说默认计算机只会做加法, 例:5+(-3) => 5 - 3
    乘法、除法是通过左移<<和右移>>来实现
    正数高位补0 负数高位补1。python中由于没有限制位数,所以高位的0和1是物理不存在的。

转换

  • 正数:
    原码 = 反码 = 补码
  • 负数:
    反码 = 原码取反(除高位)
    补码 = 反码加1
    反码 = 补码减1
    原码 = 反码取反(除高位)
    原码 = 补码取反加1
    补码 = 原码取反加1

位运算

运算符

为了说明位运算运算符的运算规则,运算符及其子标题内容以A=60=0b 0011 1100B=13=0b 0000 1101来举例。

运算符的计算优先级从高到低,依次为~、&、^、|

按位与运算符 &

Python | 数的进制及其位运算_第1张图片

  • 语法:
    参与运算的两个值, 如果两个相应位都为1,则该位的结果为1, 否则为0。
  • 举例:
    A & B = 0b 0011 1100 & 0b 0000 1101 = 0b 1100

0011 1100
0000 1101
0000 1100


按位或运算符 |

如果为负数,则按其补码形式参加按位或运算符 | 运算。
Python | 数的进制及其位运算_第2张图片

  • 语法:
    参与运算的两个值, 只要两个相应的二进位有一个为1时,结果位就为1。
  • 举例:
    A & B = 0b 0011 1100 | 0b 0000 1101 = 0b 11 1101

0011 1100
0000 1101
0011 1101


按位异或运算符 ^

Python | 数的进制及其位运算_第3张图片

  • 语法:
    参与运算的两个值, 只要两个相应的二进位值不相同,则结果位为1,否则为0。
  • 举例:
    A ^ B = 0b 0011 1100 ^ 0b 0000 1101 = 0b11 0001

0011 1100
0000 1101
    11 0001


按位取反运算符 ~

Python | 数的进制及其位运算_第4张图片

  • 语法:
    对数据的每个二进制位取反,即把1变为0,把0变为1 。~x类似于-x-1
  • 举例:
    ~A = -0b111101

0011 1100
1100 0011


左移动运算符 <<

Python | 数的进制及其位运算_第5张图片

  • 语法:
    运算数的各二进位全部左移若干位,由<<右边的数字指定了移动的位数,高位丢弃,低位补0。
  • 举例:
    A << 2 = 0b 1111 0000

0011 1100
1111 0000


右移动运算符 >>

Python | 数的进制及其位运算_第6张图片

  • 语法:
    >>左边的运算数的各二进位全部右移若干位,>>右边的数字指定了移动的位数。
  • 举例:
    A >> 2 = 0b 1111

0011 1100
1111


应用

按位与运算符 &

为了介绍按位与运算符 &的应用,此处及其子标题以0x3001d3c4来举例。

清零

快速对某一段数据单元的数据清零,即将其全部的二进制位为0,则只要与一个各位都为零的数值相与那么结果为零。。

  • 清零所有bit
    0x3001d3c4 & 0x0 = 0x0
提取指定位数

获得指定位数的数字。方法为,找一个数,对应X要取的位,该数的对应位为1,其余位为零,此数与X进行“与运算”可以得到X中的指定位。
0x3001d3c4为十六进制,通过十六进制>>二进制部分的方法使用hex(input).replace('0x', '')拿到其数字位数为8
1位十六进制数字相对应4位二进制数字。
0x3001d3c4若转换为二进制应该为32位。

  • 获得bit [20:0]
    0x3001d3c4 & 0xfffff = 0x1d3c4
    bit [20:0]为低位20位, 相当于0b 1111 1111 1111 1111, 又或者0x FFFF
  • 获得bit [4:0]
    0x3001d3c4 & 0xf = 0x4
    bit [4:0]为低位4位,相当于0b 1111,又或者0xF
保留最后一个1

保留最后一个1到最低位的数字
~ 0x3001d3c4 & 0x3001d3c4 = 0

  • 保留最后一个1
    - 0x3001d3c4 & 0x3001d3c4 = 0x4
    相当于0b100

判断奇偶性

1& 运算,相当于仅保留最后一位bit数字。

在计算机中,位与的符号是 &,运算过程是 false & false = falsetrue & false = falsetrue & true = true,故任何一个数 & 1 的结果有 2

  • 0 & 1 = 0
  • 1 & 1 = 1
  • 2 & 1 = 0
  • 3 & 1 = 1
  • 1234 & 1 = 0
  • 4321 & 1 = 1

奇数的二进制表示的末位为 1,偶数末位为 0。故可以通过运算结果来判断给定数字的奇偶性。

下面,我们分析几个例子。3987 都是十进制数:
3 & 1 在计算过程是:

11
01
---
01

所以 3 & 1 = 1

987 & 1 在计算过程是:

1111011011
0000000001
----------------
0000000001

所以 987 & 1 = 1


实例

  1. 比如在数据库中,获取所有奇数的 id,就可以直接:
select id from mytable where id & 1
  1. 在编程中判断一个数是否为奇数:
int number = 789;
if (number & 1){
	print("此数为奇数")
} else {
	print("此数为偶数")
}

按位或运算符 |

为了介绍按位或运算符 |的应用,此处及其子标题以0x3001d3c4来举例。

使指定位数置1

找到一个数,对应X要置1的位,该数的对应位为1,其余位为零。此数与X相或可使X中的某些位置1。

  • 翻转bit [7:0]
    0x3001d3c4 | 0xff = 0x3001d3ff
    bit [7:0]为低位8位, 相当于0b 1111 1111, 又或者0x FF

按位异或运算符 ^

为了介绍按位异或运算符 ^的应用,此处及其子标题以0x3001d3c4来举例。

翻转指定位数

使特定位翻转 找一个数,对应X要翻转的各位,该数的对应位为1,其余位为零,此数与X对应位异或即可。

  • 翻转bit [11:0]
    0x3001d3c4 ^ 0xfff = 0x3001dc3b
    bit [11:0]为低位12位, 相当于0b 1111 1111 1111, 又或者0x FFF
  • 翻转所有bit
    0x3001d3c4 ^ 0xffffffff = 0xcffe2c3b
保留原值
  • 保留所有bit
    0x3001d3c4 ^ 0x00000000 = 0x3001d3c4
交换a和b
x = x ^ y   
y = x ^ y  
x = x ^ y  

按位取反运算符 ~

为了介绍按位取反运算符 ~ 的应用,此处及其子标题以0xd3c5来举例。

使最后一位置0

~1的值为1111111111111110,再按&运算,最低位一定为0。
因为“~”运算符的优先级比算术运算符、关系运算符、逻辑运算符和其他运算符都高。

  • 使最后一位置0
    0xd3c5 & ~1 = 0xd3c4

左移动运算符 <<

为了介绍左移动运算符 <<的应用,此处及其子标题以0xd3c4来举例。

  • 翻倍
    (0xd3c4 << 0x1) // 0xd3c4 = 0x2

右移动运算符 >>

为了介绍右移动运算符 >>的应用,此处及其子标题以0x3001d3c4来举例。

  • 减半
    0xd3c4 // (0xd3c4 >> 1) = 0x2

总结

使用01来简单总结运算符的语法。

1 & 1 = 1, 1 | 1 = 1, 1 ^ 1 = 0

1 & 0 = 0, 1 | 0 = 1, 1 ^ 0 = 1

0 & 1 = 0, 0 | 1 = 1, 0 ^ 1 = 1

0 & 0 = 0, 0 | 0 = 0, 0 ^ 0 = 0

  • &: 有00
  • |: 有11
  • ^: 同01
  • ~: 前01, 前10
  • <<: 左1位乘2
  • >>: 右1位除2

参考链接

写本文时有参考以下链接

% todo
【技巧总结】位运算装逼指南
leetcode—-位运算(python)

进制

二进制

Python 中的按位运算符 |【生长吧!Python!】

十六进制

字节、bit、16进制

转换

Python 二进制,十进制,十六进制转换
Python int与string之间的转化

位运算

位运算与数的二进制 ( python, 位运算I )
按位与、或、非、异或总结
Python 位操作(Bitwise Operation) 详解
Python获取数字的二进制值


  1. Python eval() 函数 ↩︎

  2. 位与:一个数&1的结果 ↩︎

你可能感兴趣的:(Python,python)