3

I need to convert a float value to binary. This value can be from 0 to 99.99.

I saw that if the value is an int and between 0 to 255 I just have to do

n = [255]
num = byte(n)

How is not possible directly convert a float to binary (I think), my first step was multiply my float number *100 and have an integer from 0 to 9999.

Now I need 4 bytes to represent the number.

It is possible do something like this arduino code (below)?

n = 9999
byte = pl[4];

pl[0] = (byte) ((n & 0xFF000000) >> 24 );
pl[1] = (byte) ((n & 0x00FF0000) >> 16 );
pl[2] = (byte) ((n & 0x0000FF00) >> 8 );
pl[3] = (byte) ((n & 0X000000FF));

Basically I'm applying a mask, but I don't know how to do it with python because I'm a noob. :/

MORE INFO:

The objective is to reduce the length of my result to send this with a wireless protocol. That's why I'm converting it to byte.

Thank you very much

4
  • can you clarify some more? for ex. if number is 12.34. What do you expect as output? 1100.100010 or after multiplying it with 100, you want 010011010010?? Commented Dec 7, 2019 at 13:37
  • I need the int value, 1234 Commented Dec 7, 2019 at 13:45
  • I still think it might be good to know your exact context to give you the best advice. Any reason to convert to 4 bytes and not just two bytes, which would be sufficient for your numbers? Does this have to be memory efficient / compatible with something existing? Also what will you do with these bytes? Write them to disk? send them over the network via UDP, a custom TCP protocol, HTTP? Commented Dec 7, 2019 at 14:22
  • Yes sorry, I just need 2 bytes I mistake it. I need to send this info and I need to reduce it length because I'm using a IoT protocol Commented Dec 7, 2019 at 14:59

4 Answers 4

2

One equivalent would be

x=2049
p0 = (x>>24)&255
p1 = (x>>16)&255
p2 = (x>>8)&255
p3 = x&255
Sign up to request clarification or add additional context in comments.

Comments

2
def f2b(a):
import math
binary = []
for i in range(100):
    a=a*2
    if a<1:
        binary.append(0)
    else:
        binary.append(1)
    if a==0:
        break
    a,b=math.modf(a)
binary=''.join(str(d) for d in binary)
return binary[:-1]

It is not a perfect way to do it but it works perfectly. Input any floating value ( ex. 0.25 ) with is divisible by 2, the output will be binary value let's say "10".

Thank you

1 Comment

Remember that Stack Overflow isn't just intended to solve the immediate problem, but also to help future readers find solutions to similar problems, which requires understanding the underlying code. This is especially important for members of our community who are beginners, and not familiar with the syntax. Given that, can you edit your answer to include an explanation of what you're doing and why you believe it is the best approach?
1

As per your comments You need this:

number = float(input("Enter any number:"))
decimal = int(str(number).split(".")[0])
print(decimal)
mantissa= int(str(number).split(".")[1])
print(mantissa)
if mantissa != 0:
    pass
else:
    mantissa = 0
int_num = decimal*(10**(len(str(mantissa))))+mantissa

You'll get the integer value of that number without decimal point. Now you can convert that into binary directly.

6 Comments

the number will be converted to an integer and you can create a binary, but in this process you will have lost the position of the decimal point except you sacrifice another byte for it
Yup. But this was the solution as per the discussion with @NEA in comments as he wanted this result only.
What I meant is, that this solution auto-guesses the mantissa length instead of assuming 2 (increased complexity) IMHO it's not advantageous and in some boundary cases even not desirable. It makes it impossible to convert and unconvert data predictably, as 12.34, 123.4 would be both converted to 1234 and the reverse operation wouldn't know where to place the decimal point. If you only input valid data it wouldn't make a difference, but whenever possible I suggest defensive programming and in the given case the defensive implementation would even be simpler.
Yeah you're right. We need extra name for the place of decimal here.
if sender and receiver agree upfront on the number of digits after the '.' (e.g. 2), then no need for extra byte, but then it should be hard coded on sender and receiver side
|
1

Yes you can do exactly the same thing in python.

This would be the literal translation of your code.

n = int(floatnumber * 100 + 0.5)
bytes_to_write = bytes([(n>>24)&255, (n>>16)&255, (n>>8) & 255, n & 255])

However you could also use the struct module ( https://docs.python.org/3.6/library/struct.html ) and ( https://docs.python.org/3.6/library/struct.html#format-characters ) for the format characters:

import struct
n = int(floatnumber * 100 + 0.5)
bytes_to_write = struct.pack(">l", n)

storing the int as big endian byte sequence

For creating only two bytes use

n = int(floatnumber * 100 + 0.5)
bytes_to_write = bytes([(n>>8) & 255, n & 255])

or

import struct
n = int(floatnumber * 100 + 0.5)
bytes_to_write = struct.pack(">H", n)

2 Comments

added a two bytes solution
Please also note that n = int(floatnumber * 100 + 0.5) ensures, that any float is rounded correctly to the closest float with two digits after the decimal point. Not sure if rounding is really needed in your context or whether the floats are already with two digits only if numbers are already rounded to two digits, then you can remove the ` + 0.5` from above code. However if you leave it it doesn't do any harm and if you ever enter an unrounded number it will be rounded

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.