本文介绍了两个补码的Python(尽可能少的位)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试输出负数的二进制表示形式,每次的可用字节最少.

I am trying to output the binary representation of an negative number with the least bytes available each time.

示例:

-3 -> 101
-10 -> 10110

推荐答案

以下是使用Python 3整数的.bit_length方法执行此操作的方法.它还使用字符串.format方法将整数转换为二进制字符串.对于非负数,此函数返回以'0'开头的字符串,以便可以将它们与负数区分开.

Here's a way to do this using the .bit_length method of Python 3 integers. It also uses the string .format method to do the integer to binary string conversion. This function returns a string starting with '0' for non-negative numbers so that they can be distinguished from negative numbers.

def twos_complement(n):
    m = n + 1 if n < 0 else n
    bitlen = 1 + m.bit_length()
    mask = (1 << bitlen) - 1
    return '{0:0{1}b}'.format(n & mask, bitlen)

for i in (-10, -3, 0, 3, 10):
    print('{:3}: {}'.format(i, twos_complement(i)))

print('- ' * 30)

for i in range(-15, 16):
    print(i, twos_complement(i))

输出

-10: 10110
 -3: 101
  0: 0
  3: 011
 10: 01010
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-15 10001
-14 10010
-13 10011
-12 10100
-11 10101
-10 10110
-9 10111
-8 1000
-7 1001
-6 1010
-5 1011
-4 100
-3 101
-2 10
-1 1
0 0
1 01
2 010
3 011
4 0100
5 0101
6 0110
7 0111
8 01000
9 01001
10 01010
11 01011
12 01100
13 01101
14 01110
15 01111


工作原理

Python使用二进制补码的修改形式来表示整数. Python整数没有大小限制,因此负整数的行为就好像前导1位的无限个数一样,如关于按位运算符的Python Wiki文章.


How it works

Python uses a modified form of two's complement to represent integers. Python integers have no size limit, so negative integers behave as if they have an infinite number of leading 1 bits, as explained in the Python Wiki article on Bitwise Operators.

int.bit_length方法告诉我们表示一个数字所需的最少位数,我们希望再加上一位,以便所有非负数都以0开头,所有负数都以1开头.我们需要稍作修改,以确保格式-2**n的数字只会得到一个前导一位,我们通过在计算位长时对所有负数加1来做到这一点.

The int.bit_length method tells us the minimum number of bits required to represent a number, we want one more bit than that so that all our non-negative numbers will start with 0 and all the negative numbers start with a 1. We need to modify that slightly to ensure that numbers of the form -2**n will only get a single leading one bit, we do that by adding 1 to all the negative numbers when calculating the bit length.

要选择我们想要的位,我们需要适当长度的位掩码.如果位长度为4,则我们希望掩码为1111 = 2**4 - 1;我们可以使用幂运算来计算它,但是使用位移更有效:(1 << bitlen) - 1.然后,我们执行按位与运算n & mask以选择所需的位.幸运的是,当执行屏蔽操作时,Python给我们提供了一个非负数. :)

To select the bits we want we need a bit mask of the appropriate length. If the bit length is 4, we want a mask of 1111 = 2**4 - 1; we _could calculate it by using exponentiation, but it's more efficient to use bit shifting: (1 << bitlen) - 1. We then do the bitwise AND operation n & mask to select the bits we want. Fortunately, Python gives us a non-negative number when we perform such masking operations. :)

最后,我们使用.format方法将结果整数转换为字符串.我们使用嵌套格式规范,因此我们可以动态指定输出字符串的正确长度.在

Finally we convert the resulting integer to a string using the .format method. We use a nested format specification so we can dynamically specify the correct length of the output string. In

'{0:0{1}b}'.format(n & mask, bitlen)

格式规范的第一个0表示我们正在转换参数列表(n & mask)中的0 arg的值,:0{1}b表示要将其转换为二进制,并在必要时用前导零填充,使用参数列表(bitlen)中的1 arg的值作为字符串的总长度.

the first 0 of the format spec says that we're converting the value of the 0 arg in the argument list (n & mask), the :0{1}b says to convert it to binary, padded with leading zeroes if necessary, using the value of the 1 arg in the argument list (bitlen) as the total string length.

您可以在格式字符串中了解嵌套格式规范文档的语法部分:

这篇关于两个补码的Python(尽可能少的位)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-30 16:15