python-Struktur "packen erfordert ein bytes-Objekt-Länge 8", während die Umwandlung von binay zu schweben

Ich bin derzeit versuchen, um Binärdateien in den Wagen und Umgekehrt über das struct-Modul. Meine Funktion arbeitet mit bestimmten Werten, wie 2.0 oder 14.0, aber es funktioniert nicht mit Werten wie 1.0.

Ich habe den code aus einer anderen Frage, und verändert es von python2 auf Python ist3.

import struct

def bin_to_float(b):
    """ convert binary string to float """
    bf = int_to_bytes(int(b, 2), 8)  # 8 bytes needed for IEEE 754 binary64
    bf = bytes(bf, 'UTF-8')
    print(bf)
    return struct.unpack('<d', bf)[0]

def int_to_bytes(n, minlen):  # helper function
    """ int/long to byte string """
    nbits = n.bit_length() + (1 if n < 0 else 0)  # plus one for any sign bit
    nbytes = (nbits+7)//8  # number of whole bytes
    bytes = []
    for i in range(nbytes):
        bytes.append(chr(n & 0xff))
        n >>= 8   
    # zero pad if needed
    if minlen > 0 and len(bytes) < minlen:
        bytes.extend((minlen-len(bytes)) * '0')
    bytes.reverse()  # put high bytes at beginning
    return ''.join(bytes)

# tests

def float_to_bin(f):
    """ convert float to binary string """
    ba = struct.pack('>d', f)
    s = ''.join('{:08b}'.format(b) for b in ba)
    # strip off leading zeros
    for i in range(len(s)):
        if s[i] != '0':
             break
    else:  # all zeros
        s = '0'
        i = 0
    return s[i:]

import math

floats = [2.0, 1.0, -14.0, 12.546, math.pi]


for f in floats:
    binary = float_to_bin(f)
    print ('float_to_bin(%f): %r' % (f, binary))
    float = bin_to_float(binary)
    print ('bin_to_float(%r): %f' % (binary, float))
    print ()

Das problem scheint zu sein, dass ich beim codieren des str in bytes, bekomme ich 9 bytes statt 8, aber das passiert nur manchmal. Dies ist die Konsole Lesungen:

float_to_bin(2.000000): '100000000000000000000000000000000000000000000000000000000000000'
b'@\x00\x00\x00\x00\x00\x00\x00'
bin_to_float('100000000000000000000000000000000000000000000000000000000000000'): 0.000000

float_to_bin(1.000000): '11111111110000000000000000000000000000000000000000000000000000'
b'?\xc3\xb0\x00\x00\x00\x00\x00\x00'
Traceback (most recent call last):
  File "C:/Users/arzuffi pc test/Desktop/prova struct.py", line 47, in <module>
    float = bin_to_float(binary)
  File "C:/Users/arzuffi pc test/Desktop/prova struct.py", line 8, in bin_to_float
    return struct.unpack('<d', bf)[0]
struct.error: unpack requires a bytes object of length 8

Ich kann nicht scheinen, um herauszufinden, warum dies geschieht und wie Sie zu verhindern :/

Jemand weiß, warum das so ist?

Vielen Dank im Voraus.

EDIT: J. J. Hakala, antwortete genial, also ich poste die Antwort bis hier:

import struct

def bin_to_float(b):
    """ convert binary string to float """
    return struct.unpack('<d', struct.pack('<Q', int(b, 2)))[0]

def float_to_bin(f):
    """ convert float to binary string """
    return '{:b}'.format(struct.unpack('<Q', struct.pack('<d', f))[0])

Wenn jemand will, das gleiche zu tun mit 32 bit float, dies sollte gut sein:

import struct

def bin_to_float(b):
    """ convert binary string to float """
    return struct.unpack('<f', struct.pack('<L', int(b, 2)))[0]
def float_to_bin(f):
    """ convert float to binary string """
    return '{:b}'.format(struct.unpack('<L', struct.pack('<f',f))[0])

Vielen Dank allerseits!!!

  • int_to_bytes zu sein scheint, mit Unicode-strings statt byte-strings.
  • Seite-Hinweis: die Verwendung bytes wie ein Variablenname ist eine schreckliche Idee, die Sie selbst mit Hilfe des built-in bytes anderswo; wenn Sie es benötigt, in der gleichen Funktion, die Sie nicht haben, das original und Sie würden sich komische Fehler).
  • bytes = bytearray() könnte geeigneter sein, dann bytes = []. Mit der bytearray - bytes(bf, 'UTF-8') vermieden werden können.
Schreibe einen Kommentar