需要帮助理解 Python 中的二进制转换

Need help understanding binary conversion in Python

或者我猜一般是二进制。我显然对编码很陌生,所以我会很感激这里的任何帮助。

我刚开始学习将数字转换为二进制,特别是二进制补码。该课程提供了以下用于转换的代码:

num = 19

if num < 0:
    isNeg = True
    num = abs(num)
else:
    isNeg = False
result = ''
if num == 0:
    result = '0'
while num > 0:
    result = str(num % 2) + result
    num = num // 2
if isNeg:
    result = '-' + result

这向我提出了几个问题,在做了一些研究(主要是在 Stack Overflow 上)之后,我发现自己比以前更困惑了。希望有人能为我分解更多东西。以下是其中一些问题:

  1. 我认为代码建议只在二进制数的前面附加一个 - 以显示其负数对应是完全错误的。看起来 bin() 做同样的事情,但你不需要翻转位并添加 1 或其他东西吗?除了方便 comprehend/read?

  2. 还有其他原因吗
  3. 在阅读 here and one of the answers in particular 时说 Python 在二进制补码中并没有真正起作用,而是模仿它的其他东西。对我来说,这里的断开连接是 Python 向我展示了一件事,但以不同的方式存储数字。再一次,这只是为了方便使用吗? bin()是用补码还是Python的方法?

  4. 跟进那个,上面答案中提到的'sign-magnitude'格式与二进制补码有何不同?

  5. 教授根本不谈论 8 位、16 位、64 位等,我在阅读这篇文章时看到了很多。这种区别从何而来,Python 是否使用了区别?或者这些名称是否特定于我可能正在编写的程序?

  6. 很多这些帖子我只提到了 Python 如何存储整数。这是否表明它以不同的方式存储浮动,或者它们只是泛泛而谈?

当我写下这一切时,我有点意识到也许我在学习如何游泳之前潜入了深水区,但我很好奇,并且喜欢在移动之前对事物有更深入的了解上。

don't you have to flip the bits and add a 1 or something?

是的,对于两个补码表示法,您将所有位取反并加一以获得负数。

Is bin() using two's complement or Python's method?

二进制补码是在电子设备中表示负数的一种实用方法,电子产品只能包含 0 和 1。在内部,微处理器使用二进制补码来表示负数,所有现代微处理器都这样做。有关详细信息,请参阅有关计算机体系结构的教科书。

how does the 'sign-magnitude' format mentioned in the above answer differ from two's complement?

您应该看看这段代码的作用及其存在的原因:

while num > 0:
    result = str(num % 2) + result
    num = num // 2

I thought it was outright wrong that the code suggested just appending a - to the front of a binary number to show its negative counterpart. It looks like bin() does the same thing, but don't you have to flip the bits and add a 1 or something? Is there a reason for this other than making it easy to comprehend/read?

你必须以某种方式将数字指定为负数。您可以添加另一个符号 (-),在最开始添加符号位,使用补码,使用两个 s-complement,或其他一些完全 made-up 有效的方案。数字的 ones'- 和 two's-complement 表示都需要固定位数,这对于 Python 整数不存在:

>>> 2**1000
1071508607186267320948425049060001810561404811705533607443750
3883703510511249361224931983788156958581275946729175531468251
8714528569231404359845775746985748039345677748242309854210746
0506237114187795418215304647498358194126739876755916554394607
7062914571196477686542167660429831652624386837205668069376

自然的解决方案是在前面加上一个减号。您可以类似地编写自己的 bin() 版本,它要求您指定位数和 return 数字的两个 s-complement 表示形式。

Was reading here and one of the answers in particular said that Python doesn't really work in two's complement, but something else that mimics it. The disconnect here for me is that Python shows me one thing but is storing the numbers a different way. Again, is this just for ease of use? Is bin() using two's complement or Python's method?

Python 是一种 high-level 语言,因此您并不真正了解(或关心)您的特定 Python 运行时如何 interally存储整数。无论您使用 CPython、Jython、PyPy、IronPython 还是其他东西,语言规范只定义了它们的行为方式,而不是它们在内存中的表示方式。 bin() 只需要一个数字并使用二进制数字将其打印出来,就像将 123 转换为 base-2 一样。

Follow-up to that one, how does the 'sign-magnitude' format mentioned in the above answer differ from two's complement?

Sign-magnitude 通常将数字 n 编码为 0bXYYYYYY...,其中 X 是符号位,YY... 是 non-negative 量级。由于表示形式,将数字编码为 two's-complement 的算术更优雅,而 sign-magnitude 编码需要对符号相反的数字进行特殊处理。

The Professor doesn't talk at all about 8-bit, 16-bit, 64-bit, etc., which I saw a lot of while reading up on this. Where does this distinction come from, and does Python use one? Or are those designations specific to the program that I might be coding?

不,Python 没有为其整数定义最大大小,因为它不是 low-level。 2**1000000 可以很好地计算,如果您有足够的内存,2**10000000 也可以。 n 位数字出现在您的硬件使您的数字达到一定大小更有利时。例如,处理器的指令可以快速处理 32 位数字,但不能处理 87 位数字。

A lot of these posts I've only reference how Python stores integers. Is that suggesting that it stores floats a different way, or are they just speaking broadly?

这取决于您的 Python 运行时使用的是什么。通常浮点数类似于 C doubles,但这不是必需的。