bit_manipulation 二进制位操作
bit_manipulation 二进制位操作
-
binary_and(a: int, b: int) -> str
整数二进制 and 操作
对两个整形参数,先转换成二进制,对2个二进制数据进行 and 与操作,返回 二进制字符制 -
binary_or(a: int, b: int) -> str
or 或 操作 -
binary_xor(a: int, b: int) -> str
xor 异或 操作 -
binary_count_setbits(a: int) -> int
转换二进制数,统计“1” 的数量
其算法为: bin(a).count("1") -
binary_count_trailing_zeros(a: int) -> int
统计属随“0” 数量
其算法为:int(log2(a & -a)) -
binary_shift
二进制移位,包含:- logical_left_shift(number: int, shift_amount: int) -> str
将 number: int 转换二进制后,左移 shift_amount: int 位,返回 二进制字符串 - logical_right_shift(number: int, shift_amount: int) -> str
将 number: int 转换二进制后,左移 shift_amount: int 位,返回 二进制字符串
- logical_left_shift(number: int, shift_amount: int) -> str
-
twos_complement(number: int) -> str
二进制补码
原码, 反码, 补码的基础概念和计算方法- 原码
原码就是符号位加上真值的绝对值, 即用第一位表示符号, 其余位表示值. 比如如果是8位二进制:[+1]原 = 0000 0001 [-1]原 = 1000 0001
- 反码
反码的表示方法是:
正数的反码是其本身
负数的反码是在其原码的基础上, 符号位不变,其余各个位取反.[+1] = [00000001]原 = [00000001]反 [-1] = [10000001]原 = [11111110]反
```
- 补码
补码的表示方法是:
正数的补码就是其本身
负数的补码是在其原码的基础上, 符号位不变, 其余各位取反, 最后+1. (即在反码的基础上+1)
``` [+1] = [00000001]原 = [00000001]反 = [00000001]补 [-1] = [10000001]原 = [11111110]反 = [11111111]补 ```
- 原码
为何设置原码、补码、反码
计算机只能识别0和1,使用的是二进制。而在日常生活中人们使用的是十进制,并且我们用的数值有正负之分。于是在计算机中就用一个数的最高位存放符号(0为正,1为负)。这就是机器数的原码了。
有了数值的表示方法就可以对数进行算术运算,但是很快就发现用带符号位的原码进行乘除运算时结果正确,而在加减运算的时候就出现了问题,如下:假设字长为8bits
(1) 10 - (1)10 = (1)10 + (-1)10 = (0)10
(0 0000001)原 + (1 0000001)原 = (1 0000010)原 = ( -2 ) 显然不正确。
因为在两个整数的加法运算中是没有问题的,于是就发现问题出现在带符号位的负数身上。对除符号位外的其余各位逐位取反就产生了反码。反码的取值空间和原码相同且一一对应。下面是反码的减法运算:
(1)10 - (1)10 = (1)10 + (-1)10 = (0)10
(0 0000001)反 + (1 1111110)反 = (1 1111111)反 = ( -0 ) 有问题。
(1)10 - (2)10 = (1)10 + (-2)10 = (-1)10
(0 0000001)反 + (1 1111101)反 = (11111110)反 = (-1) 正确。
问题出现在(+0)和(-0)上,在人们的计算概念中零是没有正负之分的。(印度人首先将零作为标记并放入运算之中,包含有零号的印度数学和十进制计数对人类文明的贡献极大)。
于是就引入了补码概念。负数的补码就是对反码加一,而正数的补码不变,正数的原码反码补码是一样的。在补码中用(-128)代替了(-0),这个是人为规定的,所以补码的表示范围为:
(-1280127)共256个。
范例:
代码
[bit_manipulation*.py]{..\src\bit_manipulation*.py}
"""
Prepare
1. sys.path 中增加 TheAlgorithms\src 子模块
"""
import sys
sys.path.append('E:\dev\AI\TheAlgorithms\src')
案例一:
binary_and(a: int, b: int) -> str
并将其结果 与 (与操作) a & b 的二进制值(bin) 进行对比
from bit_manipulation.binary_and_operator import binary_and
"""
"""
print(binary_and(25, 32)) # '0b000000'
print (bin(25 & 32))
print(binary_and(37, 50)) # '0b100000'
print (bin(37 & 50))
print(binary_and(21, 30)) # '0b10100'
print (bin(21 & 30))
print(binary_and(58, 73)) # '0b0001000'
print (bin(58 & 73))
print(binary_and(0, 255)) # '0b00000000'
print (bin(0 & 255))
print(binary_and(256, 256)) # '0b100000000'
print (bin(256 & 256))
'''
print(binary_and(0, -1)) # ValueError
# print (bin(0 & (-1))
print(binary_and(0, 1.1)) # TypeError
# print (bin(0 & 1.1))
print(binary_and("0", "1")) # TypeError
# print (bin("0" & "1"))
'''
0b000000
0b0
0b100000
0b100000
0b10100
0b10100
0b0001000
0b1000
0b00000000
0b0
0b100000000
0b100000000
'\nprint(binary_and(0, -1)) # ValueError\n# print (bin(0 & (-1))\nprint(binary_and(0, 1.1)) # TypeError\n# print (bin(0 & 1.1))\nprint(binary_and("0", "1")) # TypeError\n# print (bin("0" & "1"))\n'
案例二:
binary_or(a: int, b: int) -> str
并将其结果 与 (或操作)a | b 的二进制值(bin) 进行对比
from bit_manipulation.binary_or_operator import binary_or
"""
"""
print(binary_or(25, 32)) # '0b111001'
print (bin(25 | 32))
print(binary_or(37, 50)) # '0b010111'
print (bin(37 | 50))
print(binary_or(21, 30)) # '0b01011'
print (bin(21 | 30))
print(binary_or(58, 73)) # '0b1110011'
print (bin(58 | 73))
print(binary_or(0, 255)) # '0b11111111'
print (bin(0 | 255))
print(binary_or(256, 256)) # '0b000000000'
print (bin(256 | 256))
'''
print(binary_or(0, -1)) # ValueError
# print (bin(0 | (-1)))
print(binary_or(0, 1.1)) # TypeError
# print (bin(0 | 1.1))
print(binary_or("0", "1")) # TypeError
# print (bin("0" | "1"))
'''
0b111001
0b111001
0b110111
0b110111
0b11111
0b11111
0b1111011
0b1111011
0b11111111
0b11111111
0b100000000
0b100000000
'\nprint(binary_or(0, -1)) # ValueError\n# print (bin(0 | (-1)))\nprint(binary_or(0, 1.1)) # TypeError\n# print (bin(0 | 1.1))\nprint(binary_or("0", "1")) # TypeError\n# print (bin("0" | "1"))\n'
案例三:
binary_xor(a: int, b: int) -> str
并将其结果 与 (异或操作) a ^ b 的二进制值(bin) 进行对比
from bit_manipulation.binary_xor_operator import binary_xor
"""
"""
print(binary_xor(25, 32)) # '0b111001'
print (bin(25 ^ 32))
print(binary_xor(37, 50)) # '0b010111'
print (bin(37 ^ 50))
print(binary_xor(21, 30)) # '0b01011'
print (bin(21 ^ 30))
print(binary_xor(58, 73)) # '0b1110011'
print (bin(58 ^ 73))
print(binary_xor(0, 255)) # '0b11111111'
print (bin(0 ^ 255))
print(binary_xor(256, 256)) # '0b000000000'
print (bin(256 ^ 256))
'''
print(binary_xor(0, -1)) # ValueError
# print (bin(0 ^ (-1)))
print(binary_xor(0, 1.1)) # TypeError
# print (bin(0 ^ 1.1))
print(binary_xor("0", "1")) # TypeError
# print (bin("0" ^ "1"))
'''
0b111001
0b111001
0b010111
0b10111
0b01011
0b1011
0b1110011
0b1110011
0b11111111
0b11111111
0b000000000
0b0
'\nprint(binary_xor(0, -1)) # ValueError\n# print (bin(0 ^ (-1)))\nprint(binary_xor(0, 1.1)) # TypeError\n# print (bin(0 ^ 1.1))\nprint(binary_xor("0", "1")) # TypeError\n# print (bin("0" ^ "1"))\n'
案例四
binary_count_setbits 二进制统计集合位的数量
binary_count_setbits(a: int) -> int
= bin(a).count("1")
from bit_manipulation.binary_count_setbits import binary_count_setbits
"""
"""
print(binary_count_setbits(25)) # 3
print(binary_count_setbits(36)) # 2
print(binary_count_setbits(16)) # 1
print(binary_count_setbits(58)) # 4
print(binary_count_setbits(4294967295)) # 32
print(binary_count_setbits(0)) # 0
'''
print(binary_count_setbits(-10)) # ValueError
print(binary_count_setbits(0.8)) # TypeError
print(binary_count_setbits("0")) # TypeError
'''
3
2
1
4
32
0
'\nprint(binary_count_setbits(-10)) # ValueError\nprint(binary_count_setbits(0.8)) # TypeError\nprint(binary_count_setbits("0")) # TypeError\n'
案例五
binary_count_trailing_zeros(a: int) -> int
统计属随“0” 数量
其算法为:int(log2(a & -a))
from bit_manipulation.binary_count_trailing_zeros import binary_count_trailing_zeros
"""
"""
print(bin(25))
print(bin(25 & (-25)))
print(binary_count_trailing_zeros(25)) # 0
print(bin(36))
print(bin(36 & (-36)))
print(binary_count_trailing_zeros(36)) # 2
print(bin(16))
print (bin(16 & (-16)))
print(binary_count_trailing_zeros(16)) # 4
print(bin(58))
print(bin(58 & (-58)))
print(binary_count_trailing_zeros(58)) # 1
print(bin(4294967295))
print(bin(4294967295 & (-4294967295)))
print(binary_count_trailing_zeros(4294967295)) # 32
print(bin(0))
print(bin(0 & (-0)))
print (0 & (-0))
print(binary_count_trailing_zeros(0)) # 0
'''
print(binary_count_trailing_zeros(-10)) # ValueError
print(binary_count_trailing_zeros(0.8)) # TypeError
print(binary_count_trailing_zeros("0")) # TypeError
'''
0b11001
0b1
0
0b100100
0b100
2
0b10000
0b10000
4
0b111010
0b10
1
0b11111111111111111111111111111111
0b1
0
0b0
0b0
0
0
'\nprint(binary_count_trailing_zeros(-10)) # ValueError\nprint(binary_count_trailing_zeros(0.8)) # TypeError\nprint(binary_count_trailing_zeros("0")) # TypeError\n'
案例六
binary_shift
二进制移位,包含:
- logical_left_shift(number: int, shift_amount: int) -> str
将 number: int 转换二进制后,左移 shift_amount: int 位,返回 二进制字符串 - logical_right_shift(number: int, shift_amount: int) -> str
将 number: int 转换二进制后,左移 shift_amount: int 位,返回 二进制字符串
from bit_manipulation.binary_shifts import logical_left_shift,logical_right_shift
"""
"""
print ('binary_shift of logical_left_shift:')
print(logical_left_shift(0, 1)) # '0b00'
print(logical_left_shift(1, 1)) # '0b10'
print(logical_left_shift(1, 5)) # '0b100000'
print(logical_left_shift(17, 2)) # '0b1000100'
print(logical_left_shift(1983, 4)) # '0b111101111110000'
# print(logical_left_shift(1, -1)) # ValueError
print ('binary_shift of logical_right_shift:')
print(logical_right_shift(0, 1)) # '0b0'
print(logical_right_shift(1, 1)) # '0b0'
print(logical_right_shift(1, 5)) # '0b0'
print(logical_right_shift(17, 2)) # '0b100'
print(logical_right_shift(1983, 4)) # '0b1111011'
# print( logical_right_shift(1, -1)) # ValueError
binary_shift of logical_left_shift:
0b00
0b10
0b100000
0b1000100
0b111101111110000
binary_shift of logical_right_shift:
0b0
0b0
0b0
0b100
0b1111011
案例七
twos_complement(number: int) -> str
二进制补码
参数:number: int 为负数或0
返回:二进制补码的二进制字符串
from bit_manipulation.binary_twos_complement import twos_complement
"""
"""
print(bin(0))
print(twos_complement(0)) # '0b0'
print(bin(-1))
print(twos_complement(-1)) # '0b11'
print(bin(-5))
print(twos_complement(-5)) # '0b1011'
print(bin(-17))
print(twos_complement(-17))# '0b101111'
print(bin(-207))
print(twos_complement(-207)) # '0b100110001'
# print(bin(1))
# print( twos_complement(1)) # ValueError
0b0
0b0
-0b1
0b11
-0b101
0b1011
-0b10001
0b101111
-0b11001111
0b100110001