为了账号安全,请及时绑定邮箱和手机立即绑定

Python中float的二进制表示(位不是十六进制)

Python中float的二进制表示(位不是十六进制)

炎炎设计 2019-12-25 15:58:50
如何获取字符串作为32位浮点数的二进制IEEE 754表示形式?例1.00->'00111111100000000000000000000000000000'
查看完整描述

3 回答

?
慕侠2389804

TA贡献1719条经验 获得超6个赞

您可以使用以下struct软件包:


import struct

def binary(num):

    return ''.join(bin(ord(c)).replace('0b', '').rjust(8, '0') for c in struct.pack('!f', num))

将其打包为网络字节排序的浮点数,然后将每个结果字节转换为8位二进制表示形式并将其串联起来:


>>> binary(1)

'00111111100000000000000000000000'

编辑:有人要求扩大解释。我将使用中间变量对此进行扩展,以注释每个步骤。


def binary(num):

    # Struct can provide us with the float packed into bytes. The '!' ensures that

    # it's in network byte order (big-endian) and the 'f' says that it should be

    # packed as a float. Alternatively, for double-precision, you could use 'd'.

    packed = struct.pack('!f', num)

    print 'Packed: %s' % repr(packed)


    # For each character in the returned string, we'll turn it into its corresponding

    # integer code point

    # 

    # [62, 163, 215, 10] = [ord(c) for c in '>\xa3\xd7\n']

    integers = [ord(c) for c in packed]

    print 'Integers: %s' % integers


    # For each integer, we'll convert it to its binary representation.

    binaries = [bin(i) for i in integers]

    print 'Binaries: %s' % binaries


    # Now strip off the '0b' from each of these

    stripped_binaries = [s.replace('0b', '') for s in binaries]

    print 'Stripped: %s' % stripped_binaries


    # Pad each byte's binary representation's with 0's to make sure it has all 8 bits:

    #

    # ['00111110', '10100011', '11010111', '00001010']

    padded = [s.rjust(8, '0') for s in stripped_binaries]

    print 'Padded: %s' % padded


    # At this point, we have each of the bytes for the network byte ordered float

    # in an array as binary strings. Now we just concatenate them to get the total

    # representation of the float:

    return ''.join(padded)

以及一些示例的结果:


>>> binary(1)

Packed: '?\x80\x00\x00'

Integers: [63, 128, 0, 0]

Binaries: ['0b111111', '0b10000000', '0b0', '0b0']

Stripped: ['111111', '10000000', '0', '0']

Padded: ['00111111', '10000000', '00000000', '00000000']

'00111111100000000000000000000000'


>>> binary(0.32)

Packed: '>\xa3\xd7\n'

Integers: [62, 163, 215, 10]

Binaries: ['0b111110', '0b10100011', '0b11010111', '0b1010']

Stripped: ['111110', '10100011', '11010111', '1010']

Padded: ['00111110', '10100011', '11010111', '00001010']

'00111110101000111101011100001010'


查看完整回答
反对 回复 2019-12-25
?
慕仙森

TA贡献1827条经验 获得超7个赞

这是一个丑陋的...


>>> import struct

>>> bin(struct.unpack('!i',struct.pack('!f',1.0))[0])

'0b111111100000000000000000000000'

基本上,我只是使用struct模块将float转换为int ...


这是一个稍微好一点的使用ctypes:


>>> import ctypes

>>> bin(ctypes.c_uint.from_buffer(ctypes.c_float(1.0)).value)

'0b111111100000000000000000000000'

基本上,我构造一个,float并使用相同的内存位置,但是我将其标记为c_uint。该c_uint的值是一个Python整数,您可以使用内建bin的功能。


查看完整回答
反对 回复 2019-12-25
?
紫衣仙女

TA贡献1839条经验 获得超15个赞

将问题分为两部分,可以更彻底地解决此问题。


第一种是将浮点数转换为具有等效位模式的int:


def float32_bit_pattern(value):

    return sum(ord(b) << 8*i for i,b in enumerate(struct.pack('f', value)))

接下来将int转换为字符串:


def int_to_binary(value, bits):

    return bin(value).replace('0b', '').rjust(bits, '0')

现在将它们结合起来:


>>> int_to_binary(float32_bit_pattern(1.0), 32)

'00111111100000000000000000000000'


查看完整回答
反对 回复 2019-12-25
  • 3 回答
  • 0 关注
  • 1028 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信