Bit twiddling floating point numbers

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Jeff.Goldfinkle@gmail.com

    Bit twiddling floating point numbers

    Hi All

    Is there a simple way to twiddle the bits of a float? In particular, I
    would like to round my float to the n most significant bits.

    For example - 0.123 in binary is 0.000111111
    Rounding to 4 bits I get 0.0001.

    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?
  • Grant Edwards

    #2
    Re: Bit twiddling floating point numbers

    On 2008-03-05, Jeff.Goldfinkle @gmail.com <Jeff.Goldfinkl e@gmail.comwrot e:
    Is there a simple way to twiddle the bits of a float? In particular, I
    would like to round my float to the n most significant bits.
    >
    For example - 0.123 in binary is 0.000111111
    Rounding to 4 bits I get 0.0001.
    >
    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?
    Just use the bitwise and/or/not operators: & | ~

    --
    Grant Edwards grante Yow! Half a mind is a
    at terrible thing to waste!
    visi.com

    Comment

    • Grant Edwards

      #3
      Re: Bit twiddling floating point numbers

      On 2008-03-05, Grant Edwards <grante@visi.co mwrote:
      On 2008-03-05, Jeff.Goldfinkle @gmail.com <Jeff.Goldfinkl e@gmail.comwrot e:
      >Any suggestions?
      >
      Just use the bitwise and/or/not operators: & | ~
      Oh, I forgot to mention the shift operators << and >>

      --
      Grant Edwards grante Yow! All of life is a blur
      at of Republicans and meat!
      visi.com

      Comment

      • Jeff.Goldfinkle@gmail.com

        #4
        Re: Bit twiddling floating point numbers

        On Mar 5, 10:48 pm, Grant Edwards <gra...@visi.co mwrote:
        On 2008-03-05, Grant Edwards <gra...@visi.co mwrote:
        >
        On 2008-03-05, Jeff.Goldfin... @gmail.com <Jeff.Goldfin.. .@gmail.comwrot e:
        Any suggestions?
        >
        Just use the bitwise and/or/not operators: & | ~
        >
        Oh, I forgot to mention the shift operators << and >>
        >
        --
        Grant Edwards grante Yow! All of life is a blur
        at of Republicans and meat!
        visi.com
        thanks for the reply but I'm still unsure as to how to continue. Using
        the bitwise operators will help me deal with integers but I really
        want to work with floats. For instance - which bits do I twiddle to
        round my float to the nearest number of bits?

        Jeff

        Comment

        • Grant Edwards

          #5
          Re: Bit twiddling floating point numbers

          On 2008-03-05, Jeff.Goldfinkle @gmail.com <Jeff.Goldfinkl e@gmail.comwrot e:
          thanks for the reply but I'm still unsure as to how to
          continue. Using the bitwise operators will help me deal with
          integers but I really want to work with floats.
          In your original post, you said that you've got the values as
          integers.
          For instance - which bits do I twiddle to round my float to
          the nearest number of bits?
          The format of a float (actually Python uses doubles) depends on
          your platform, but in all likelihood it's the IEEE-754 64-bit
          format.

          googling for "IEEE-754 format" finds some good references:


          An overview of IEEE Standard 754 floating-point representation.



          --
          Grant Edwards grante Yow! Well, I'm INVISIBLE
          at AGAIN ... I might as well
          visi.com pay a visit to the LADIES
          ROOM ...

          Comment

          • Mark Dickinson

            #6
            Re: Bit twiddling floating point numbers

            On Mar 5, 3:25 pm, "Jeff.Goldfin.. .@gmail.com"
            <Jeff.Goldfin.. .@gmail.comwrot e:
            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.7853981633974 4828
            >>e
            2
            >>int(m*2**53 )
            707423775202844 0L

            Then you can do your bit twiddling on int(m*2**53), before using
            ldexp to 'repack' the float.

            Mark

            Comment

            • Bryan Olson

              #7
              Re: Bit twiddling floating point numbers

              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.7853981633974 4828
              >>>e
              2
              >>>int(m*2**5 3)
              707423775202844 0L
              >
              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

              Comment

              • Jeff.Goldfinkle@gmail.com

                #8
                Re: Bit twiddling floating point numbers

                On Mar 6, 11:00 am, Bryan Olson <fakeaddr...@no where.orgwrote:
                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.7853981633974 4828
                >>e
                2
                >>int(m*2**53 )
                707423775202844 0L
                >
                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

                Comment

                Working...