0

I am manipulating binary values with python. Here is my statement:

I have a float value, for example: 127.136. First, I split this value in order to differenciate the integer and the fractional values, then I transform them into bytes:

   velocity = 127.136
   split_num = str(velocity).split('.')
   int_part = int(split_num[0]) # = 127
   decimal_part = int(split_num[2]) # = 136
   int_part_b = "{0:b}".format(int_part)
   decimal_part_b = "{0:b}".format(decimal_part)

I have to send the final value as a 2 bits word. The total space is 32 bits. 127 is the integer part and 136 is the fractional part. The integer part takes 16 bits and the decimal part takes 16 bits.

enter image description here

So I want to initialize 3 binary word of 32 bits like that:

final_value = 00000000000000000000000000000000
integer_value = 00000000000000000000000000000000
fractional_value = 00000000000000000000000000000000

But then how can I add the value of int_part_b from the 16th bits of integer_value so for example if int_part_b = 10011 I would like to have: integer_value = 00000000000100110000000000000000 and for the fractional one if decimal_part_b = 11110 I would like to have: fractional_value = 00000000000000000000000000011110

And at the end, I sum this two bits values to obtain: final_value = 00000000000100110000000000011110

Does anyone has any idea about how to do that?

2

2 Answers 2

4

For this encoding to make any sense, the value in the fractional part should be a faction of 2^16 (or any denominator <= 65536 you pick as a convention).

You cannot obtain the fractional part of the float value by string manipulation because that makes you lose the base10 denominator. (e.g. 0.36 and 0.036 are two different fractions but your code will produce 36 in both cases).

Note that there are a lot of different ways to encode numbers in binary (BCD for example) so you probably should be specific on that in your question

Binary encoding:

Here is one way to do it with a denominator of 2^16:

velocity = 127.136
denom    = 2**16
intPart,fracPart = divmod(round(velocity*denom),denom)
encoded = (intPart<<16) | fracPart

print(f"{encoded:032b}")
# 00000000011111110010001011010001

Or, more straightforwardly (but only if denom is 2**16):

encoded = round(velocity*2**16)
print(f"{encoded:032b}")
# 00000000011111110010001011010001

Here, the value in the right part (fractional) is 8913, representing a fraction of 8913/65536 (0.1360015...) which is as close to 0.136 as a binary fraction over 16 bits can get.

Decoding the value:

int(encoded[:16],2) + int(encoded[16:],2)/denom
# 127.13600158691406

Decimal encoding:

If you want to represent the fractional part in base 10, you'll have to decide on a base10 denominator that fits within 16 bits (e.g. 10000) and compute your fractional part accordingly.

velocity = 127.136
denom    = 10000
intPart,fracPart = divmod(round(velocity*denom),denom)
encoded = (intPart<<16) | fracPart

print(f"{encoded:032b}")
# 00000000011111110000010101010000

Now the fractional part is 1360 representing a fraction of 1360/10000 (0.136) which doesn't lose precision compared to the base 10 original (as long as there are no more than 4 decimal digits)

Decoding the value:

int(encoded[:16],2) + int(encoded[16:],2)/denom
# 127.136
Sign up to request clarification or add additional context in comments.

Comments

2

You don't really need 3 differend words, just use the binary shift operator and sum the integer and decimal parts like this:

final_value = (int_part << 16) + decimal_part
print("{:032b}".format(final_value))

So here you shift your integer part 16 bits to the left and then you add your decimal part to it so they will occupy there respective 16-bit words of the 32-bit word.

2 Comments

What happens with 127.0136?
Was not part of the question.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.