0

I think I am overthinking this probelem, but I can't seem to solve it. I am reading in little endian floats from a file (range (-1,1)), and want to convert them to fixed point 32b.

If I read in the value 0xA0C1943B, that equates to a float of 0.0045396835. If I want to represent that as a fixed32_31, it would be 0x00129834.

Is there a simple way in python to get from 0xA0C1943B to 0x00129834?

toozie21
  • 341
  • 2
  • 6
  • 15
  • Can you clarify what the fixed point format is? How many bits total, and where's the point? For the example values that you give, the fixed representation is obtained by scaling the float by 2**28 and then rounding to the nearest int. Where does that 28 come from? – Mark Dickinson Oct 15 '15 at 07:11

2 Answers2

0

I believe you want to use the python struct module:

import struct
print struct.pack('<f', some_float)

'<f' is a format string representing a little endian float (4 bytes). If this doesn't work for you should check the documentation for formats that will work for you.

https://docs.python.org/2/library/struct.html

shafeen
  • 2,431
  • 18
  • 23
  • hmmm, this might be where I am overthinking things. I was actually reading in the value using your command. I can print out the value and it looks fine, but I think it is probably still being stored as a "float" in the variable. If I want to go to a fixed value, that is where I thought I needed to make a conversion.... – toozie21 Oct 14 '15 at 17:15
0

You can think of a fixed-point integer as the numerator of a fraction, possibly with a bias applied. In your case, you want -1.0 to map to -INT_MAX, and 1.0 to map to INT_MAX (that is, 2**31 - 1).

A couple of turns of the algebra crank gives us:

fixed = int(flt * (INT_MAX/2))

Note that the rounding isn't perfect there. If you care about the exact behavior of -1.0, 0.0, and/or 1.0, slightly more complicated formulas apply.

Sneftel
  • 40,271
  • 12
  • 71
  • 104
  • Thanks, but I think we might not be on the same page somewhere. I am OK with not including -1 and 1 in my range (so it is purely a fraction), so the integer portion of the fixed value is just the sign bit. When I run your algorithm on the float 0.00453968346119, I get the hex value 0x8094c19e. That is 32b, but would be a negative value in fixed<32,31> representation. – toozie21 Oct 14 '15 at 17:44
  • @toozie21 Ah, so you're using a signed representation. I'll update the answer. – Sneftel Oct 14 '15 at 17:57
  • I totally missed your unsigned U in your variable, that would have helped clued me in. I still think something is missing though. For my 0.00453968346119 float I get a hex of 0x4a60cf, and for a float of -0.00708158267662, it is giving a hex of -0x74064f. Both of these have a 1 in the MSb, which would make them both negative. I am guessing the addition of the negative sign is doing something there that I need to account for. – toozie21 Oct 14 '15 at 18:17
  • 0x4a60cf, as a 32 bit integer, has a 0 in the MSB. Its binary representation is 00000000010010100110000011001111. "-0x74064f" is not a normal way to express a hexadecimal constant, but presumably it's just representing -7603791, with a binary representation of 11111111100010111111100110110001. – Sneftel Oct 14 '15 at 18:24