【问题标题】:Manually calculating IEEE-754 floating point fractions and splitting up the bits - Python手动计算 IEEE-754 浮点分数并拆分位 - Python
【发布时间】:2021-11-17 06:24:36
【问题描述】:

我正在想办法做到这一点:

假设我的 IEEE-754 浮点数的小数部分是 0b10110011001100110011010

我正在尝试获取每个位并将其乘以对应于它的位位置的 2 的幂,然后将它们全部加起来。

就像这样:1*2-1+ 0*2-2 + 1*2-3 + 1*2-4 + 0*2-5 + 0 * 2-6 + ...

我这辈子都不知道如何将数字分成几位。

理想情况下是这样的:

In [33]: value = 0x6f

In [34]: result = function(value)

In [35]: result

Out[35]: [0,1,1,0,1,1,1,1]

不一定是列表,但元组也可以。

然后我很有信心我可以使用for i in result 函数来获得我需要的答案。但是,如果您对如何制作第二部分有想法,我也会全神贯注!

有什么想法吗?

【问题讨论】:

  • bin(0x6f)是你需要的
  • 你想把你的十六进制值转换成二进制吗?
  • 似乎是 XY 问题。你真正想要得到什么? float 的确切值?它在内存中的内部表示?
  • 无需处理单独的位。 0b10110011001100110011010 / 2**23 == 0.7000000476837158.
  • @dan04 我正在尝试获取内存中的表示。在 PowerPC 架构中,单精度浮点值存储在 64 位寄存器中,但使用 25 个小数位。不是标准的 23。寄存器中剩余的 29 位为 0。我希望能够计算 PowerPC 单精度浮点值并查看它在 64 位寄存器中的表示。所以它看起来像这样:`符号位_Exp _Fraction_zeros`0b0_00000000_1111111111111111111111111_00000000000000000000000000000

标签: python python-3.x floating-point binary ieee-754


【解决方案1】:

如果您想获取float 的原始位,则可以使用struct.pack

>>> struct.pack('@d', 0.7)
b'ffffff\xe6?'
>>> struct.pack('>d', 0.7)
b'?\xe6ffffff'

前缀是@,表示依赖于平台的“本机顺序、大小和对齐方式”(默认设置,但@ 明确表示),而> 表示“big-endian, std.大小和对齐方式”。

big-endian 转换为位序列 0_01111111110_0110011001100110011001100110011001100110011001100110,即:

  • 符号位为0,表示该数为正数。
  • 1022 的指数。
  • 0x6666666666666 的有效位。

回想一下,标准化 IEEE 754 double 的值是 (-1)**sign * 2 ** (exponent - 1023) * (1 + significand / 2**52)。插入符号 = 0、指数 = 1022 和有效数字 = 0x6666666666666 给出预期的 0.7(或者准确地说,0.69999999999999999555910790149937383830547332763671875)。

如果您想使用数学函数而不是 struct,那么 math.frexp 是您的朋友。它返回一个 (significand, exponent) 的元组,使得 significand * 2**exponent 给出原始数字。但是,它会缩放指数,以便有效数字在区间 [0.5, 1) 中,而不是 [1, 2) 中,因此在下面的代码中,我将指数偏差写为 1022 而不是 1023。

def ieee_double_fields(x):
    sign = 0
    if x < 0:
        sign = 1
        x = -x
    significand, exponent = math.frexp(x)
    return (sign, exponent + 1022, int((significand * 2 - 1) * 2**52))

这将返回一个由 1 位符号、11 位指数和 52 位有效数组成的整数元组(没有隐式前导 1 位)。

非正规(包括 ±0.0)、无穷大和 NaN 的处理留给读者作为练习。

【讨论】:

    猜你喜欢
    • 2018-01-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-15
    • 2012-01-06
    • 2014-10-18
    • 2012-03-13
    相关资源
    最近更新 更多