retrieve bitwise float representation

Mark Dickinson dickinsm at gmail.com
Wed Jun 10 10:24:56 EDT 2009


Ulrich Eckhardt <eckhardt at satorlaser.com> wrote:
> Hi!
> 
> I need to pack a floating point value into a vector of 32-bit unsigned
> values in IEEE format. Further, I maintain a CRC32 checksum for integrity
> checking. For the latter, I actually need the float as integral value.
> 
> [...]

You could try using frexp to extract the significand and exponent of
the float, and then pack those values directly into an integer,
following the IEEE 754 format.  For example:

Python 2.6.2 (r262:71600, Jun  8 2009, 14:57:27) 
[GCC 4.0.1 (Apple Computer, Inc. build 5367)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from struct import pack, unpack
>>> from math import frexp, copysign
>>> x = -34.125 
>>> unpack('<L', pack('<f', x))[0]
3255336960L
>>> m, e = frexp(abs(x))
>>> (e+125 << 23) + int(m*2.**24) + (2**31 if x < 0.0 else 0)
3255336960L

The above formula works for most x that are exactly representable as
an IEEE single-precision value, but extra effort would be required to
make it work with nans, infinities, zeros or denormals.

I'm not sure whether this is any faster than the pack/unpack route,
though.  Obviously, if you're going to convert many floats then the
2.**24 and 2**31 constants should be precalculated.

If your values aren't already exactly representable as IEEE
single-precision floats then you may have a problem with rounding: the
call to int() in the above would truncate, while the implicit
conversion from double to single precision involved in packing with
'f' is more likely to do a round-to-nearest.

-- 
Mark Dickinson



More information about the Python-list mailing list