Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

16 bit Binary conversion

I have found several ways to convert both Integer and Float values to binary, and they each have their issues. I need to take an Integer/Float input between values of 0 and 10,000, convert to a 16-digit (exactly) binary string, manipulate the bits at random, and convert back to an Integer/Float (depending on the parameter).

However, I have been using the following code:

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.

And the result is this (in picture form since I couldn't copy and paste from my terminal):

this

I understand that there are different types of binary (signed/unsigned, different bit numbers, etc.), but I need my output to be what I think is unsigned short... all of my numbers are positive values, and to allow for the bit manipulation I later use, they need to be exactly 16 digits long --> (If they are float values, I can use the extra digits of binary but just alter the first 16, and the ones that follow are just what follows the decimal point, right?)

Firstly, should I write functions for both a Float input and an Integer input?

Secondly, how do I change my code to allow for the desired output without simply using pop, etc. to cut the length of the binary to 16?

like image 315
elarr Avatar asked Aug 31 '25 01:08

elarr


1 Answers

I had the same problem and I found a simpler and shorter solution.

Here's an example:

Encode:

In [1]: val = 15

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

Or:

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

Decode:

In [6]: int(bin_, 2)
Out[6]: 15
like image 177
Benyamin Jafari Avatar answered Sep 02 '25 15:09

Benyamin Jafari