16位二进制转换

4
我找到了几种将整数和浮点数值转换为二进制的方法,它们各自都有问题。我需要将介于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位?


你如何期望将浮点值适配到16位?标准的表示方式是32位或64位。 - Mark Ransom
在原帖中,我表述得不太好(“如果它们是浮点值,我可以使用二进制的额外位数,但只需更改前16位”) - 我的意思是简单地取前16位进行变异,然后附加剩余的16位。这不是一个完美的系统,但它为整体价值引入了一些随机性。 - elarr
IEEE 754浮点值不是这样工作的...例如,32位浮点数有1个符号位、8个指数位和23个分数位,使得1.<fraction>*(2^<exponent>)可以产生浮点数。取其中的前16位只会得到符号位、指数和一部分分数。或者是分数的最后16位,具体取决于您如何分割它。而跟随小数点后面的数字则只是分数部分。 - Zrax
2个回答

10

我有同样的问题,不过我找到了一个更简单、更短的解决方案。

这里是一个例子:

编码:

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'

解码:

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

1

我看到这并不是一个很受欢迎的问题,因此我暂时把它放在这里:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接