彻底搞懂python负数的二进制存储问题,刷题有感

刷题的时候看到python的二进制存储很有特点,在网上搜索半天也没看明白,特自己总结如下。

首先需要知道:
1.python存储一个数据是无限位的。
2.python正数是按源码存储的,1的源码是0b1,负数是按照补码存储的,-1的补码(即源码取反再加一)是0xff…ffffff(无数个f),二进制就是0b后面无数个1。

因为位数是无限的,所以我们怎么操作呢?
如果这个数字在-2^31到2*31-1之前,则对它进行截断,舍去此数字 32 位以上的数字:&0xffffffff。
这样-1就变成了0x00…000ffffffff

处理完之后怎么判断数字是正数还是负数呢
首先可以这样 (a&0x80000000)>>31,如果是1,就是负数
或者可以这样 a <= 0x7fffffff,如果为False,就是负数

然后知道数字的正负了,该怎么得到他的大小呢
经过&0xffffffff之后,得到正数的32位源码和负数的32位补码,正数可以直接输出了,负数再-(~x+1),取反加一再加个负号就得到所需负数了。

负数还有一种简单方法,我们把截取掉的32位之前的位数恢复出来,然后让python识别后输出。如果不把之前的位数恢复,python只会根据这32位输出(不会把某一位当成符号位)。例如print(-1 & 0xffff)会输出65535

# 以0xffff为例,0xffffffff同理
m = -234
print(-(((m&0xffff)^ 0xffff)+1))  
# 手动操控补码输出,其中m&0xffff获得补码,然后取反加一,再加负号。+-优先级高于位运算
print(   ~((m&0xffff)^0xffff) )  
# 先m&0xffff截取,把16位之前的无限位数置0了,得到补码,
# 再^0xffff对16位取反之后对所有位取反(即除后16位之外,前面的位取反),
# 可以把16位之前的无限位数恢复至1,python自动根据补码输出

上面为两种实现方法,都会输出-234

  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值