【问题标题】:Need help understanding binary conversion in Python需要帮助理解 Python 中的二进制转换
【发布时间】:2018-08-18 15:03:14
【问题描述】:

或者我猜一般是二进制的。我显然对编码很陌生,因此我将不胜感激。

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

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 或其他东西吗?除了使其易于理解/阅读之外,还有其他原因吗?

  2. 正在阅读 hereone of the answers in particular 说 Python 并不能真正用于二进制补码,而是模仿它的其他东西。对我来说,这里的脱节是 Python 向我展示了一件事,但以不同的方式存储数字。再说一遍,这只是为了方便使用吗? bin()是用二进制补码还是Python的方法?

  3. 跟进那个,上面答案中提到的“符号-幅度”格式与二进制补码有何不同?

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

  5. 很多这些帖子我只提到了 Python 如何存储整数。这是暗示它以不同的方式存储浮动,还是只是泛泛而谈?

当我写完这一切时,我有点意识到,也许我在学习如何游泳之前就已经深入到了深处,但我对此很好奇,喜欢在继续前进之前对事物有更深入的了解。

【问题讨论】:

  • bin() 不返回二进制位,它返回二进制数的字符串表示形式。
  • Python 不使用固定大小的整数(即 32 位或 64 位)。而且,正如chrisz 所说,bin 返回一个字符串,表示 二进制数字系统 中的整数。这与 python 用来表示整数的实际底层位的方式不同。是的,无论如何,Python int 对象不使用二进制补码。
  • 请参阅en.wikipedia.org/wiki/64-bit_computing 了解有关 n 位起源的想法。我记得读过一些 4 位的旧英特尔 CPU 数据表。通常可用的 CPU 寄存器位宽,或由寄存器指定时的内存地址宽度,或数据总线宽度...
  • 如果您想知道 int 的实际存储方式(在最新版本的 CPython 中),请查看源代码,特别是 longintrep.h,或者查看 superhackyinternals 以使用 Python 中的位边。但简短的版本是(IIRC)它是一个尽可能多的 30 位“数字”列表,符号在最高位。
  • 同时,Jython 或 IronPython 可能使用完全不同的东西。围绕本机 JVM 或 .NET bigint 类型的包装器可能有意义。或者,它可能使用 30 位“数字”,但它们存储在一个绳索中,该绳索通常是一个用于大量数字的连续数组,但并非总是如此。只要能提供与 CPython 的实现相同的接口和大致相同的性能保证,就是有效的。

标签: python binary converter


【解决方案1】:

您不必翻转位并添加 1 或其他东西吗?

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

bin() 是使用二进制补码还是 Python 的方法?

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

上述答案中提到的“符号幅度”格式如何 不同于二进制补码?

你应该看看这段代码做了什么以及为什么会出现:

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

【讨论】:

    【解决方案2】:

    我认为代码建议只在二进制数前面附加一个 - 以显示其负数是完全错误的。看起来 bin() 做同样的事情,但你不必翻转位并添加 1 或其他东西吗?除了使其易于理解/阅读之外,还有其他原因吗?

    您必须以某种方式指定负数。您可以添加另一个符号 (-),在开头添加一个符号位,使用 one'-complement,使用 two's-complement 或其他一些完全虚构的方案。数字的补码表示和补码表示都需要固定位数,而 Python 整数不存在这种情况:

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

    自然的解决方案是在前面加上一个减号。您可以类似地编写自己的 bin() 版本,要求您指定位数并返回数字的二进制补码表示。

    正在阅读here,其中一个答案特别说Python并不能真正用于二进制补码,而是模仿它的其他东西。对我来说,这里的脱节是 Python 向我展示了一件事,但以不同的方式存储数字。再说一次,这只是为了方便使用吗? bin() 是使用二进制补码还是 Python 的方法?

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

    跟进那个,上面答案中提到的“符号-幅度”格式与二进制补码有何不同?

    符号幅度通常将数字n 编码为0bXYYYYYY...,其中X 是符号位,YY... 是非负幅度的二进制数字。由于表示形式,将数字编码为二进制补码的算术更加优雅,而符号幅度编码需要对相反符号数的运算进行特殊处理。

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

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

    很多这些帖子我只提到了 Python 如何存储整数。这是暗示它以不同的方式存储浮动,还是只是泛泛而谈?

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

    【讨论】:

    • 感谢您提供的所有信息。几个问题: 1. 那么符号大小与补码相同吗?或者它只是一个类似的想法? 2. 你能详细说明一下吗,或者你有一个链接来说明你所说的关于浮点数的内容吗? 3. 很多这归结为不知道香肠是怎么做的,只是吃了它?我不知道这里的内部结构,所以我应该只关注它是如何输出的?
    • @dylosaur:类似,请查看维基百科页面中的signed number representations,特别是该部分的末尾。如果您有兴趣,您绝对可以阅读how CPython implements 所有这些数字数据类型,但它们的实现方式(可以随时更改)并没有真正改变您的 Python 脚本的执行方式。
    • 酷。我喜欢那个解释。非常感谢!
    • 值得注意的是,Python 不仅没有为整数定义 特定 大小,而且根本没有 any 最大大小。你可以使用int 来获取足够大的数字来加密,甚至更大;它会占用更多内存,并且速度会变慢,但您永远不必担心环绕或OverflowError(除非您明确执行诸如 (int(float('inf'))) 之类的操作等。
    猜你喜欢
    • 2021-12-21
    • 1970-01-01
    • 2022-10-15
    • 2011-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-20
    相关资源
    最近更新 更多