16-битное двоичное преобразование - PullRequest
0 голосов
/ 26 июня 2018

Я нашел несколько способов преобразовать значения Integer и Float в двоичные, и у каждого из них есть свои проблемы. Мне нужно взять целочисленное значение / число с плавающей запятой между значениями от 0 до 10000 , преобразовать в 16-значную (точно) двоичную строку , обработать биты случайным образом и преобразовать обратно в целое число / число с плавающей запятой (в зависимости от параметра).

Однако я использовал следующий код:

def convert_to_binary(value):
    '''
    Converts a float to a 16-bit binary string.
    '''
    [d] = struct.unpack('>Q', struct.pack('>d', value))
    return str('{:016b}'.format(d))

def convert_back(bin_num):
    ''' 
    Converts binary string to a float. 
    '''
    print type(bin_num) 
        print bin_num
    bf = int_to_bytes(int(bin_num, 2), 8)  # 8 bytes needed for IEEE 754 binary64.
        print struct.unpack('>d', bf)[0]
    return struct.unpack('>d', bf)[0]

#   return struct.unpack('d', struct.pack('Q', bin_num))[0]
    #bin_num.pack('B*').unpack('g').first

def int_to_bytes(n, minlen=0):  # Helper function
    '''
    Turns integer/long to byte string.
    '''
    nbits = n.bit_length() + (1 if n < 0 else 0)  # +1 for any sign bit.
    nbytes = (nbits+7) // 8  # Number of whole bytes.
    b = bytearray()
    for _ in range(nbytes):
        b.append(n & 0xff)
        n >>= 8
    if minlen and len(b) < minlen:  # Zero padding needed?
        b.extend([0] * (minlen-len(b)))
    return bytearray(reversed(b))  # High bytes first.

И результат такой (в виде картинки, так как я не мог скопировать и вставить с моего терминала):

this

Я понимаю, что существуют разные типы двоичных файлов (со знаком / без знака, с разными битовыми числами и т. Д.), Но мне нужно, чтобы мой вывод был таким, какой я считаю коротким без знака ... все мои числа являются положительными значениями, и, чтобы использовать битовые манипуляции, которые я позже использую, они должны иметь длину ровно 16 цифр -> (Если они являются числами с плавающей запятой, я могу использовать дополнительные двоичные числа, но просто измените первые 16, и последующие - это то, что следует за десятичной точкой, верно?)

Во-первых, я должен написать функции для ввода с плавающей запятой и целочисленного ввода?

Во-вторых, как я могу изменить свой код для обеспечения желаемого вывода без простого использования pop и т. Д., Чтобы сократить длину двоичного файла до 16?

Ответы [ 2 ]

0 голосов
/ 09 октября 2018

У меня была такая же проблема, поэтому я голосовал за твой вопрос и ответ, но нашел более простое и короткое решение.

Вот пример:

Код:

In [1]: val = 15

In [2]: bin_ = '{0:016b}'.format(val)
In [3]: bin_
Out[3]: '0000000000001111'

Или:

In [4]: bin_ = bin(val)[2:].zfill(16)
In [5]: bin_
Out[5]: '0000000000001111'

Decode:

In [6]: int(bin_, 2)
Out[6]: 15

[ Примечание ]:

Это будет работать на Python 2.7 и Python 3.x

0 голосов
/ 26 июня 2018

Это не очень популярный вопрос, на который я могу ответить, поэтому я подожду пока:

def convert_to_binary(value):
    '''
    Converts a float to a 16-bit binary string.
    '''
    n = ['0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0']
    value = int(value)
    if value > 2**15:
        if value > 2**16:
            print "Value too large"
        else:
            n[0] = '1'
            value = value - (2**15)
    if value > 2**14:
        n[1] = '1'
        value = value - (2**14)
    if value > 2**13:
        n[2] = '1'
        value = value - (2**13)
    if value > 2**12:
        n[3] = '1'
        value = value - (2**12)
    if value > 2**11:
        n[4] = '1'
        value = value - (2**11)
    if value > 2**10:
        n[5] = '1'
        value = value - (2**10)
    if value > 2**9:
        n[6] = '1'
        value = value - (2**9)
    if value > 2**8:
        n[7] = '1'
        value = value - (2**8)
    if value > 2**7:
        n[8] = '1'
        value = value - (2**7)
    if value > 2**6:
        n[9] = '1'
        value = value - (2**6)
    if value > 2**5:
        n[10] = '1'
        value = value - (2**5)
    if value > 2**4:
        n[11] = '1'
        value = value - (2**4)
    if value > 2**3:
        n[12] = '1'
        value = value - (2**3)
    if value > 2**2:
        n[13] = '1'
        value = value - (2**2)
    if value > 2**1:
        n[14] = '1'
        value = value - (2**1)
    if value >= 2**0:
        n[15] = '1'
        value = value - (2**0)

        n = ''.join(n)
        n = str(n)

        print str(n)
        return str(n)

def convert_back(bin_num):
    """
    Converts binary string to a float.
    """
    value = 0
    print type(bin_num)
    n = list(bin_num)

    if n[0] == '1':
        value = value + (2 ** 15)
    if n[1] == '1':
        value = value + (2 ** 14)
    if n[2] == '1':
        value = value + (2 ** 13)
    if n[3] == '1':
        value = value + (2 ** 12)
    if n[4] == '1':
        value = value + (2 ** 11)
    if n[5] == '1':
        value = value + (2 ** 10)
    if n[6] == '1':
        value = value + (2 ** 9)
    if n[7] == '1':
        value = value + (2 ** 8)
    if n[8] == '1':
        value = value + (2 ** 7)
    if n[9] == '1':
        value = value + (2 ** 6)
    if n[10] == '1':
        value = value + (2 ** 5)
    if n[11] == '1':
        value = value + (2 ** 4)
    if n[12] == '1':
        value = value + (2 ** 3)
    if n[13] == '1':
        value = value + (2 ** 2)
    if n[14] == '1':
        value = value + (2 ** 1)
    if n[15] == '1':
        value = value + (2 ** 0)

    print value

    return value
...