【问题标题】:Two Complement's Python (with as least bits as possible)两个 Complement 的 Python(尽可能少)
【发布时间】:2017-03-14 21:51:45
【问题描述】:

我试图输出一个负数的二进制表示,每次可用的字节数最少。

例子:

-3 -> 101
-10 -> 10110

【问题讨论】:

  • 你可以展示一下吗?
  • 你的问题是?给我写这段代码?给我一个这样做的图书馆?这两个都跑题了,不好意思。展示您的研究以及您尝试解决的问题。
  • -3 101 怎么样? bin(-3) == '-0b11'
  • 如果输入为正,你想输出什么?你想让 5 返回 '0101' 吗?我假设是这样,否则你将无法区分正数和负数。
  • @LutzHorn Two's complement

标签: python python-3.x binary


【解决方案1】:

这是一种使用 Python 3 整数的.bit_length 方法的方法。它还使用字符串.format 方法进行整数到二进制字符串的转换。该函数为非负数返回一个以'0'开头的字符串,以便与负数区分开来。

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 article on Bitwise Operators 中所述。

int.bit_length 方法告诉我们表示一个数字所需的最小位数,我们想要比这多一位,这样我们所有的非负数都以 0 开头,所有负数都以 1 开头。我们需要稍微修改一下,以确保-2**n 形式的数字只会得到一个前导一位,我们通过在计算位长时将所有负数加 1 来做到这一点。

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

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

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

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

您可以在文档的Format String Syntax 部分阅读有关嵌套格式规范的信息:

format_spec 字段还可以包含嵌套的替换字段 在其中。这些嵌套的替换字段可能包含一个字段名称, 转换标志和格式规范,但不是更深的嵌套 允许。 format_spec 中的替换字段是 在解释 format_spec 字符串之前替换。这 允许动态指定值的格式。

【讨论】:

  • 你能解释一下代码的逻辑吗?谢谢它似乎工作
  • -8 应该是 1000 吗?
  • @ΣΤΑΥΡΟΣΑΒΡΑΜΙΔΗΣ 抱歉耽搁了,但希望我写的东西是有意义的。 :)
猜你喜欢
  • 2010-09-27
  • 1970-01-01
  • 2019-02-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-13
相关资源
最近更新 更多