retrieve bitwise float representation
dickinsm at gmail.com
Wed Jun 10 16:24:56 CEST 2009
Ulrich Eckhardt <eckhardt at satorlaser.com> wrote:
> 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))
>>> m, e = frexp(abs(x))
>>> (e+125 << 23) + int(m*2.**24) + (2**31 if x < 0.0 else 0)
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.
More information about the Python-list