python 负数补码存储问题

补码

正数补码是本身,

负数补码是 符号位不变,其余逐位求反再加1。

相加减运算规则(a+b):

  (1) a ->补码a   b -> 补码b 

  (2)按位相加,将第一位舍弃

  (3)补码还原【原码就是补码的补码】

   具体二进制补码问题,详见 ->https://blog.csdn.net/zhuozuozhi/article/details/80896838链接2

python中负数补码

python中的正负数[正数]都是以补码的形式存在的。

在c中负数直接使用补码的方式存储的[用2的补码的方式表示负数],但是在python中 是用原码+'-'产生的。而且十进制、十六进制下的负数表示不同

a = bin(-3)
print(a)
 
a = bin(3)
print(a)
 
b = bin(-3 & 0xffffffff)
print(b)
 
c = bin(0xfffffffd)
print(c)
 
//输出
//-0b11
//0b11
//0b11111111111111111111111111111101
//0b11111111111111111111111111111101

为了获得负数(十进制表示)的补码,需要手动将其和十六进制数0xffffffff进行按位与操作,得到结果是个十六进制数,再交给bin()进行输出,得到的才是想要的补码表示。

a = -3
a = bin(-3 & 0xffffffff) # ->十六进制数 => 二进制补码

在涉及到正负数[-30+2]运算的过程中, 应该首先将负数转成补码的形式,即利用 a& 0xffffff[求补],得到二进制负数补码的形式。

再将其与2进行加减运算后,将补码[a+b]进行还原

还原:先将 (a+b)^0xffffffff [按位取反],再整体取反 ~(a&0xffffff)。将 32 位以上的位取反,即由 0变为 1,1 至 32 位不变。[补码是变过去了,再变回来的一种操作]

a = -30
print(bin(a)) # -0b11110
b = 0b10
# print(bin(a)+b) ##error
b = 2
print(bin(a+b)) ## -0b11100
print(bin(a& 0xffffff)) #16777186 0b111111111111111111100010 ##求补
print(bin ((a&0xffffff)+b)) #  16777188 0b111111111111111111100100 -> 加完之后补码形式
c =  (a&0xffffff)+b #补码相加之后的结果
print( ~(c^0xffffff)) # -28 补码还原
print( bin(~(c^0xffffff))) # -28 ->-0b11100

涉及到的题->面试题65. 不用加减乘除做加法

参考:

【1】https://leetcode-cn.com/problems/bu-yong-jia-jian-cheng-chu-zuo-jia-fa-lcof/solution/mian-shi-ti-65-bu-yong-jia-jian-cheng-chu-zuo-ji-7/

【2】https://blog.csdn.net/qinglv1/article/details/90580013

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Foneone

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值