python中反码和补码的计算

2019年11月2日 / 8次阅读 / Last Modified 2019年11月2日
数值计算

python虽然是在某种程度上脱离了底层硬件的高级语言,它还是可以对数值的二进制机器码表示进行各种运算和操作。本文介绍如何计算反码和补码。

首先,我们介绍一下反码和补码的知识:反码,就是各位取反,很简单!补码,就是在反码的基础上加1得到。

计算机存储有符号的数,采用的就是补码!

正数的补码就是它本身,负数的补码,就是其绝对值的反码加1。符号位是最高bit位,0为正数,1为负数。在C语言中,我们使用singed和unsinged来表示此数据是否有符号,这个关键词决定了此数据在计算机中的存储表示方式。

python跟C语言在计算反码的时候,一样都是使用~符号。不过,python有它自己的细节需要注意。

>>> ~6
-7

6取反后得到-7,这是怎么回事?我们需要通过查看二进制码来分析:

>>> bin(6)
'0b110'
>>> bin(-7)
'-0b111'

bin函数看起来不够给力,对于-7,它的输出其实就是7的二进制码,前面再带一个符号。这跟我们人类的直观感受一样,这也是python的特点。因此,我们需要换一种方式,来查看6和-7的二进制码,是否真的就是取反的关系:

>>> bin((6).to_bytes(1, 'big', signed=True)[0])
'0b110'
>>> bin((-7).to_bytes(1, 'big', signed=True)[0])
'0b11111001'

真的是取反(to_bytes函数请参考:int与bytes的相互转换)!bin函数输出的bytes对象,0b后面不会有多余的0,这个要注意。我们把上面代码简化一下,并且使用~取反符号:

>>> (6).to_bytes(1, 'big', signed=True)
b'\x06'
>>> (~6).to_bytes(1, 'big', signed=True)
b'\xf9'

看16进制,可能更简单一点点。

以上证明,~符号在python中,就是直接取反。而补码,就是在取反的基础上,加1得到:

>>> (6).to_bytes(1, 'big', signed=True)
b'\x06'
>>> (~6+1).to_bytes(1, 'big', signed=True)
b'\xfa'
>>> 6 + ~6+1 == 0
True

6和-6的和是0,0x06和0xfa的和,不考虑溢出,结果也是0。

还有一种方式查看反码和补码的二进制表示,请看下面的代码:

>>> bin(6)
'0b110'
>>> bin(~6 & 0xFF)
'0b11111001'
>>> bin(~6+1 & 0xFF)
'0b11111010'

& 在python中,按位进行与(AND)运算。在表达式中引入&,就强迫python解释器将负数按照补码的方式来进行计算,最后再使用bin函数将结果的二进制显示出来。

python中的整数,不受底层硬件字节数的限制,一般情况int都是4个字节。我们用4个字节来总结以上各种计算:

>>> (6).to_bytes(4, 'big', signed=True)
b'\x00\x00\x00\x06'
>>> (~6).to_bytes(4, 'big', signed=True)
b'\xff\xff\xff\xf9'
>>> (~6+1).to_bytes(4, 'big', signed=True)
b'\xff\xff\xff\xfa'
>>>
>>> bin(6)
'0b110'  # '0b00000000000000000000000000000110'
>>> bin(~6 & 0xFFFFFFFF)
'0b11111111111111111111111111111001'
>>> bin(~6+1 & 0xFFFFFFFF)
'0b11111111111111111111111111111010'

-- EOF --

本文链接:https://www.pynote.net/archives/1429

留言区

电子邮件地址不会被公开。 必填项已用*标注


前一篇:
后一篇:

More

麦新杰的Python笔记

Ctrl+D 收藏本页


©Copyright 麦新杰 Since 2019 Python笔记

go to top