Bit twiddling floating point numbers

Jeff.Goldfinkle at gmail.com Jeff.Goldfinkle at gmail.com
Thu Mar 6 16:01:24 EST 2008


On Mar 6, 11:00 am, Bryan Olson <fakeaddr... at nowhere.org> wrote:
> Mark Dickinson wrote:
> > Jeff Goldfin wrote:
> >> I can pack and unpack a float into a long
> >> e.g.
> >> struct.unpack('I',struct.pack('f',0.123))[0]
> >> but then I'm not sure how to work with the resulting long.
>
> >> Any suggestions?
>
> > One alternative to using struct is to use math.ldexp and math.frexp:
>
> >>>> m, e = frexp(pi)
> >>>> m
> > 0.78539816339744828
> >>>> e
> > 2
> >>>> int(m*2**53)
> > 7074237752028440L
>
> > Then you can do your bit twiddling on int(m*2**53), before using
> > ldexp to 'repack' the float.
>
> Ah, those are handy. Jeff described his problem: "In particular,
> I would like to round my float to the n most significant bits."
> I think this works:
>
>    from math import frexp, ldexp, floor
>
>    def round_mantissa(x, nbits):
>        shifter = 1 << nbits
>        (m, e) = frexp(x)
>        m = floor(m * shifter + 0.5) / shifter
>        return ldexp(m, e)
>
> --
> --Bryan
Thanks for the help - your function seems to fit the bill even better
than gmpy since I don't need an external module. In my case I'll use
m = floor(m * shifter) / shifter instead of m = floor(m * shifter +
0.5) / shifter

Jeff




More information about the Python-list mailing list