【问题标题】:Is there a python equivalent of the octave command `format bit`?是否有等效于八度命令“格式位”的python?
【发布时间】:2015-10-11 05:36:26
【问题描述】:

在八度音阶中,命令format bit 之后的所有数字输出将显示存储在内存中的数字的本机位表示。例如,

octave:1> format bit
octave:2> 0.5
ans = 0011111111100000000000000000000000000000000000000000000000000000
octave:7> 2
ans = 0100000000000000000000000000000000000000000000000000000000000000
octave:3> format
octave:4> 0.5
ans = 0.50000

在 python 中是否有一个等效的命令来显示所有数字的本机位表示(所以输出如下所示)?

>>> "equivalent of the octave format bit command"
>>> 0.5
0011111111100000000000000000000000000000000000000000000000000000

(这与 0.5 的二进制表示非常不同。)

【问题讨论】:

  • 我对此表示怀疑; Python 不鼓励了解或关心事物在内存中的存储位置和方式。你想用它做什么?
  • 相关:Binary representation of float in Python (bits not hex)。不过,这仅适用于花车。
  • @Kevin 感谢您的链接,但这并不是我想要的。 @jonsharpe 我发现在教授数值分析课时使用 format bit 八度音阶来解释浮点表示、规范化与非规范化浮点数等非常方便。但我想开始在课堂上使用 python,因此查询。

标签: python


【解决方案1】:

TL;DR;不,没有 Python 等价物

当您使用 Python 时,您不应该需要这些信息。像使用 octave 一样设置“输出模式”是不可能的(不修改 Python 本身)。如果您真的想要所有输出格式不是默认格式,您可以为此编写自定义函数,如果您使用的是 Python 3,甚至可以覆盖默认的 print 函数。

如果您只想查看数字的二进制表示,可以使用bin(number) 函数处理整数。对于浮点数,您可以使用float.hex(number)

如果我们真的想看到内部表示,它需要一些工作,一点点黑魔法和ctypes 库。使用 Python 时获取这些数据并不容易(或无论如何可用),但我创建了一个函数来向我们展示 float 是如何在内部表示的:

我们知道 Python 浮点数中的浮点数是 IEEE 754 double precision 浮点数,因此它们使用 8 个字节(64 位)的内存。

import ctypes

def show_float(x):
    asdouble = ctypes.c_double(x)
    xpointer = ctypes.addressof(asdouble)
    xdata = ctypes.string_at(xpointer, 8)
    print "".join([bin(ord(i))[2:] for i in xdata])

x = 3.14
show_float(x) # prints 1111110000101111010111010001101110001111010011000000

整数更难,因为表示在所有实现中都不相同。你可以找到一个例子here

【讨论】:

  • 我只需要这个功能来向学生展示机器表示,所以一个功能非常适合我的目的(肯定比“修改 Python”更好)。使用您的想法,我想出了可以准确显示我需要的功能(发布在下面),谢谢!
  • 不相关的问题:什么是 TL;DR;? (对不起,我是stackoverflow的新手。)
【解决方案2】:

根据@Hannes Karppila 的回答,这里有两个函数以二进制和十六进制格式显示任何数字的机器表示。它使用与该答案基本相同的逻辑,但用零填充输出以显示每个字节的“正确”长度。

import ctypes
import decimal
def print_as_octave_bit_hex(x):
  '''
  This function prints the binary representation as it would
  be printed using the format 'bit' and 'hex' in octave
  '''
  asdouble = ctypes.c_double(x)
  xpointer = ctypes.addressof(asdouble)
  xdata = ctypes.string_at(xpointer, 8)
  xbin= [(bin(i)[2:].zfill(8)) for i in xdata[-1::-1]]
  print(x, "=", x.hex(), "=", decimal.Decimal(x))
  print("representation in format 'bit' and 'hex' of octave")
  print("with spaces separating each byte")
  print(" ".join([i.zfill(8) for i in xbin]), "=",
        " ".join([hex(int(i,2))[2:].zfill(2) for i in xbin]))
  print("without spaces separating the bytes")
  print("".join([i.zfill(8) for i in xbin]), "=",
        "".join([hex(int(i,2))[2:].zfill(2) for i in xbin]))

def print_as_octave_native_bit_hex(x):
  '''
  This function prints the binary representation as it would
  be printed using the format 'native-bit' and 'native-hex' in octave
  '''
  asdouble = ctypes.c_double(x)
  xpointer = ctypes.addressof(asdouble)
  xdata = ctypes.string_at(xpointer, 8)
  xbin = [(bin(i)[2:].zfill(8)) for i in xdata]
  print(x, "=", x.hex(), "=", decimal.Decimal(x))
  print("representation in format 'native-bit' and 'native-hex' of octave")
  print("with spaces separating each byte")
  print(" ".join([(i.zfill(8))[-1::-1] for i in xbin]), "=",
        " ".join([hex(int(i,2))[2:].zfill(2) for i in xbin]))
  print("without spaces separating the bytes")
  print("".join([(i.zfill(8))[-1::-1] for i in xbin]), "=",
        "".join([hex(int(i,2))[2:].zfill(2) for i in xbin]))

x=1.1+2.2
print_as_octave_bit_hex(x)
print(" ")
print_as_octave_native_bit_hex(x)
3.3000000000000003 = 0x1.a666666666667p+1 = 3.300000000000000266453525910037569701671600341796875
representation in format 'bit' and 'hex' of octave
with spaces separating each byte
01000000 00001010 01100110 01100110 01100110 01100110 01100110 01100111 = 40 0a 66 66 66 66 66 67
without spaces separating the bytes
0100000000001010011001100110011001100110011001100110011001100111 = 400a666666666667

3.3000000000000003 = 0x1.a666666666667p+1 = 3.300000000000000266453525910037569701671600341796875
representation in format 'native-bit' and 'native-hex' of octave
with spaces separating each byte
11100110 01100110 01100110 01100110 01100110 01100110 01010000 00000010 = 67 66 66 66 66 66 0a 40
without spaces separating the bytes
1110011001100110011001100110011001100110011001100101000000000010 = 6766666666660a40

【讨论】:

  • 谢谢,他们是很好的补充。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-07-12
  • 2012-04-10
  • 1970-01-01
  • 2017-11-29
  • 1970-01-01
  • 1970-01-01
  • 2016-04-01
相关资源
最近更新 更多