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

The*_*eer 52 python floating-point binary

如何将字符串作为32位浮点的二进制IEEE 754表示?

1.00 - >'00111111100000000000000000000000'

Dan*_*ocq 59

你可以用这个struct包来做到这一点:

import struct
def binary(num):
    return ''.join(bin(ord(c)).replace('0b', '').rjust(8, '0') for c in struct.pack('!f', num))
Run Code Online (Sandbox Code Playgroud)

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

>>> binary(1)
'00111111100000000000000000000000'
Run Code Online (Sandbox Code Playgroud)

编辑:有一个扩展解释的请求.我将使用中间变量扩展它来评论每一步.

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)
Run Code Online (Sandbox Code Playgroud)

结果举几个例子:

>>> 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'
Run Code Online (Sandbox Code Playgroud)

  • 对于Python 3,您必须省略对ord()的调用,因为pack()返回一个bytes对象,它在迭代时直接产生整数. (12认同)
  • 较短的Python 3版本:struct.pack('!f',num)中c的`''.join('{:0> 8b}'。format(c))` (3认同)
  • @gciriani 将浮点格式 (`f`) 替换为 [double 格式](https://docs.python.org/3/library/struct.html#format-characters) (`d`),即 `'' .join('{:0>8b}'.format(c) for c in struct.pack('!f', num))` (2认同)

mgi*_*son 31

这是一个丑陋的......

>>> import struct
>>> bin(struct.unpack('!i',struct.pack('!f',1.0))[0])
'0b111111100000000000000000000000'
Run Code Online (Sandbox Code Playgroud)

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


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

>>> import ctypes
>>> bin(ctypes.c_uint.from_buffer(ctypes.c_float(1.0)).value)
'0b111111100000000000000000000000'
Run Code Online (Sandbox Code Playgroud)

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


The*_*eer 20

使用bitstring模块找到另一个解决方案.

import bitstring
f1 = bitstring.BitArray(float=1.0, length=32)
print f1.bin
Run Code Online (Sandbox Code Playgroud)

输出:

00111111100000000000000000000000
Run Code Online (Sandbox Code Playgroud)

  • 这些天是`f1.bin` (5认同)
  • 可以从以下网站验证该值:https://www.h-schmidt.net/FloatConverter/IEEE754.html (2认同)

Mar*_*som 8

通过将其分为两部分可以更清楚地处理这个问题.

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

def float32_bit_pattern(value):
    return sum(ord(b) << 8*i for i,b in enumerate(struct.pack('f', value)))
Run Code Online (Sandbox Code Playgroud)

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

def int_to_binary(value, bits):
    return bin(value).replace('0b', '').rjust(bits, '0')
Run Code Online (Sandbox Code Playgroud)

现在结合它们:

>>> int_to_binary(float32_bit_pattern(1.0), 32)
'00111111100000000000000000000000'
Run Code Online (Sandbox Code Playgroud)

  • `float32_bit_pattern` 在 Python 3.2+ 上可以定义为 `lambda x: int.from_bytes(struct.pack("f", x), byteorder="little")` (2认同)

Jav*_*Gom 8

With these two simple functions (Python >=3.6) you can easily convert a float number to binary and vice versa, for IEEE 754 binary64.

import struct

def bin2float(b):
    ''' Convert binary string to a float.

    Attributes:
        :b: Binary string to transform.
    '''
    h = int(b, 2).to_bytes(8, byteorder="big")
    return struct.unpack('>d', h)[0]


def float2bin(f):
    ''' Convert float to 64-bit binary string.

    Attributes:
        :f: Float number to transform.
    '''
    [d] = struct.unpack(">Q", struct.pack(">d", f))
    return f'{d:064b}'
Run Code Online (Sandbox Code Playgroud)

For example:

print(float2bin(1.618033988749894))
print(float2bin(3.14159265359))
print(float2bin(5.125))
print(float2bin(13.80))

print(bin2float('0011111111111001111000110111011110011011100101111111010010100100'))
print(bin2float('0100000000001001001000011111101101010100010001000010111011101010'))
print(bin2float('0100000000010100100000000000000000000000000000000000000000000000'))
print(bin2float('0100000000101011100110011001100110011001100110011001100110011010'))
Run Code Online (Sandbox Code Playgroud)

The output is:

0011111111111001111000110111011110011011100101111111010010100100
0100000000001001001000011111101101010100010001000010111011101010
0100000000010100100000000000000000000000000000000000000000000000
0100000000101011100110011001100110011001100110011001100110011010
1.618033988749894
3.14159265359
5.125
13.8
Run Code Online (Sandbox Code Playgroud)

I hope you like it, it works perfectly for me.


Eri*_*ric 5

为了完整起见,您可以使用numpy实现此目的:

f = 1.00
int32bits = np.asarray(f, dtype=np.float32).view(np.int32).item()  # item() optional
Run Code Online (Sandbox Code Playgroud)

然后,您可以使用b格式说明符使用填充打印此内容

print('{:032b}'.format(int32bits))
Run Code Online (Sandbox Code Playgroud)

  • 稍微整洁一点:`int32bits = np.float32(1.0).view(np.int32)` (2认同)
  • 仍然整洁:`int32bits = np.float32(1.0).view(np.int32).item()` :) (2认同)

y.s*_*hyk 5

用 Python3 的彩色版本对 Dan 的回答进行猪尾处理:

import struct

BLUE = "\033[1;34m"
CYAN = "\033[1;36m"
GREEN = "\033[0;32m"
RESET = "\033[0;0m"


def binary(num):
    return [bin(c).replace('0b', '').rjust(8, '0') for c in struct.pack('!f', num)]


def binary_str(num):
    bits = ''.join(binary(num))
    return ''.join([BLUE, bits[:1], GREEN, bits[1:10], CYAN, bits[10:], RESET])


def binary_str_fp16(num):
    bits = ''.join(binary(num))
    return ''.join([BLUE, bits[:1], GREEN, bits[1:10][-5:], CYAN, bits[10:][:11], RESET])

x = 0.7
print(x, "as fp32:", binary_str(0.7), "as fp16 is sort of:", binary_str_fp16(0.7))
Run Code Online (Sandbox Code Playgroud)

彩色表示