def fun2(a, b):
while b:
nocatty = a ^ b
catty = (a & b) << 1
a = nocatty
b = catty
return a
print(fun2(2, -4))
def func(num1, num2):
while num2:
# num1是不算进位的值,num2是进位的值
num1, num2 = (num1 ^ num2) & 0xFFFFFFFF, ((num1 & num2) << 1) & 0xFFFFFFFF
#通过查看符号位判断num1为正数还是负数,正数则直接返回。负数则返回 - ((num1 - 1) ^ 0xffffffff)
return num1 if num1 < 0x7FFFFFFF else ~(num1 ^ 0xFFFFFFFF)
print(func(-1,-5))
二进制
二进制第一位是符号位,8 位二进制数原码、反码的取值范围:[1111 1111, 0111 1111],即 [-127 , 127],补码的取值范围: [-128, 127]
原码
符号位加上真值的绝对值,即用第一位表示符号,其余位表示值
反码
正数的反码是其本身
负数的反码是在其原码的基础上, 符号位不变,其余各个位取反
所以,如果一个反码表示的是负数,人脑无法直观的看出来它的数值,通常要将其转换成原码再计算
补码
正数的补码就是其本身
负数的补码是在其原码的基础上,符号位不变,其余各位取反, 最后+1(即在反码的基础上+1)
对于负数,补码表示方式人脑无法直观看出其数值的,通常需要转换成原码在计算其数值
用补码运算的原因
1.若用原码运算
1 - 1 = 1 + (-1) = (00000001)原码 + (10000001)原码 = (10000010)原码=-2
结果错误
2.若用反码计算
1 - 1 = 1 + (-1) = (00000001)反码 +(11111110)反码 = (11111111)反码 = (10000000)原码 = -0
虽然结果正确,但出现了-0,与大家常用情况不同
0xffffffff
0xffffffff表示的是一个十六进制数
1.将其转换为十进制数
0xffffffff=4294967295
2.将其转换为二进制数
十六进制转换为二进制就是直接把每位转换成二进制
0xffffffff = 1111 1111 1111 1111 1111 1111 1111 1111 (8个F的二进制形式, 一个F占4个字节 )
即32位数都是1的二进制数
0x7FFFFFFF
0x7FFFFFFF代表int的最大值
正数与边界数 0xffffffff 按位与(&) 操作后 仍得到这个数本身
负数与边界数按位与(&) 操作后 得到的是对应二进制数的真值