本文总结如何对数字进行进制转换和位运算及其应用。
Last Modified: 2023 / 8 / 19
对于任何一个数,我们可以用不同的进位制来表示。比如:十进数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(str)
int(str, 8)
int(str, 16)
但是没有```int(str, 2)
int(12)
# 12
int('12', 16)
# 18
# 等同于将十六进制的 `0x12` 转换为十进制的 `18`
eval()
函数用来执行一个字符串表达式,并返回表达式的值 1。
以下是 eval()
方法的语法:
eval(expression[, globals[, locals]])
参数 | 描述 |
---|---|
expression |
表达式。 |
globals |
变量作用域,全局命名空间,如果被提供,则必须是一个字典对象。 |
locals |
变量作用域,局部命名空间,如果被提供,可以是任何映射对象。 |
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
bin()
oct()
int()
int(str, 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)
<<
和右移>>
来实现为了说明位运算运算符的运算规则,运算符
及其子标题内容以A=60=0b 0011 1100
和B=13=0b 0000 1101
来举例。
运算符的计算优先级从高到低,依次为~、&、^、|
&
A & B = 0b 0011 1100 & 0b 0000 1101 = 0b 1100
0011 1100
0000 1101
0000 1100
|
A & B = 0b 0011 1100 | 0b 0000 1101 = 0b 11 1101
0011 1100
0000 1101
0011 1101
^
A ^ B = 0b 0011 1100 ^ 0b 0000 1101 = 0b11 0001
0011 1100
0000 1101
11 0001
~
~x
类似于-x-1
~A = -0b111101
0011 1100
1100 0011
<<
<<
右边的数字指定了移动的位数,高位丢弃,低位补0。A << 2 = 0b 1111 0000
0011 1100
1111 0000
>>
>>
左边的运算数的各二进位全部右移若干位,>>
右边的数字指定了移动的位数。A >> 2 = 0b 1111
0011 1100
1111
为了介绍按位与运算符 &
的应用,此处及其子标题以0x3001d3c4
来举例。
快速对某一段数据单元的数据清零,即将其全部的二进制位为0,则只要与一个各位都为零的数值相与那么结果为零。。
0x3001d3c4 & 0x0 = 0x0
获得指定位数的数字。方法为,找一个数,对应X要取的位,该数的对应位为1,其余位为零,此数与X进行“与运算”可以得到X中的指定位。
0x3001d3c4
为十六进制,通过十六进制>>二进制
部分的方法使用hex(input).replace('0x', '')
拿到其数字位数为8
。
1位十六进制数字相对应4位二进制数字。
即0x3001d3c4
若转换为二进制应该为32位。
0x3001d3c4 & 0xfffff = 0x1d3c4
0b 1111 1111 1111 1111
, 又或者0x FFFF
。0x3001d3c4 & 0xf = 0x4
0b 1111
,又或者0xF
保留最后一个1到最低位的数字
~ 0x3001d3c4 & 0x3001d3c4 = 0
- 0x3001d3c4 & 0x3001d3c4 = 0x4
0b100
与 1
做 &
运算,相当于仅保留最后一位bit数字。
在计算机中,位与的符号是 &
,运算过程是 false & false = false
,true & false = false
,true & true = true
,故任何一个数 & 1
的结果有 2:
0 & 1 = 0
1 & 1 = 1
2 & 1 = 0
3 & 1 = 1
1234 & 1 = 0
4321 & 1 = 1
奇数的二进制表示的末位为 1
,偶数末位为 0
。故可以通过运算结果来判断给定数字的奇偶性。
下面,我们分析几个例子。3
和 987
都是十进制数:
3 & 1
在计算过程是:
11
01
---
01
所以 3 & 1 = 1
987 & 1
在计算过程是:
1111011011
0000000001
----------------
0000000001
所以 987 & 1 = 1
实例
id
,就可以直接:select id from mytable where id & 1
int number = 789;
if (number & 1){
print("此数为奇数")
} else {
print("此数为偶数")
}
为了介绍按位或运算符 |
的应用,此处及其子标题以0x3001d3c4
来举例。
找到一个数,对应X要置1的位,该数的对应位为1,其余位为零。此数与X相或可使X中的某些位置1。
0x3001d3c4 | 0xff = 0x3001d3ff
0b 1111 1111
, 又或者0x FF
。^
为了介绍按位异或运算符 ^
的应用,此处及其子标题以0x3001d3c4
来举例。
使特定位翻转 找一个数,对应X要翻转的各位,该数的对应位为1,其余位为零,此数与X对应位异或即可。
0x3001d3c4 ^ 0xfff = 0x3001dc3b
0b 1111 1111 1111
, 又或者0x FFF
。0x3001d3c4 ^ 0xffffffff = 0xcffe2c3b
0x3001d3c4 ^ 0x00000000 = 0x3001d3c4
x = x ^ y
y = x ^ y
x = x ^ y
~
为了介绍按位取反运算符 ~
的应用,此处及其子标题以0xd3c5
来举例。
~1
的值为1111111111111110
,再按&
运算,最低位一定为0。
因为“~”运算符的优先级比算术运算符、关系运算符、逻辑运算符和其他运算符都高。
0xd3c5 & ~1 = 0xd3c4
<<
为了介绍左移动运算符 <<
的应用,此处及其子标题以0xd3c4
来举例。
(0xd3c4 << 0x1) // 0xd3c4 = 0x2
>>
为了介绍右移动运算符 >>
的应用,此处及其子标题以0x3001d3c4
来举例。
0xd3c4 // (0xd3c4 >> 1) = 0x2
使用0
和1
来简单总结运算符的语法。
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
&
: 有0
则0
|
: 有1
则1
^
: 同0
异1
~
: 前0
后1
, 前1
后0
<<
: 左1位乘2
>>
: 右1位除2
写本文时有参考以下链接
% todo
【技巧总结】位运算装逼指南
leetcode—-位运算(python)
Python 中的按位运算符 |【生长吧!Python!】
字节、bit、16进制
Python 二进制,十进制,十六进制转换
Python int与string之间的转化
位运算与数的二进制 ( python, 位运算I )
按位与、或、非、异或总结
Python 位操作(Bitwise Operation) 详解
Python获取数字的二进制值
Python eval() 函数 ↩︎
位与:一个数&1的结果 ↩︎