"Shifting" floating point numbers

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

    "Shifting" floating point numbers

    Does anyone know of a fast way to multiply floating point numbers by
    powers of two? Conceptually, all you need to do is add to the
    mantissa. But can I write C code (or x86 assembly) to accomplish this
    without a full-blown multiply?

    For example, I'd like to be able to do the following very quickly:

    double x;
    double y;

    x = 42.13;
    y = (1 << 9) * x;

    Thanks in advance,
    Bill

  • santosh

    #2
    Re: &quot;Shifting& quot; floating point numbers

    woess...@gmail. com wrote:[color=blue]
    > Does anyone know of a fast way to multiply floating point numbers by
    > powers of two? Conceptually, all you need to do is add to the
    > mantissa. But can I write C code (or x86 assembly) to accomplish this
    > without a full-blown multiply?
    >
    > For example, I'd like to be able to do the following very quickly:
    >
    > double x;
    > double y;
    >
    > x = 42.13;
    > y = (1 << 9) * x;[/color]

    If you know the floating point representation of your implementation
    and underlying hardware, you can copy the float value to an unsiged
    long variable, shift the appropriate bits and copy the value back to
    the float variable. All this implies that you'll have to know details
    about your implementation and thus risk losing some portability.

    These days, FPU's are quite fast, so a direct multiply on the float
    should be efficient enough unless you're code is time critical.

    Comment

    • Skarmander

      #3
      Re: &quot;Shifting& quot; floating point numbers

      woessner@gmail. com wrote:[color=blue]
      > Does anyone know of a fast way to multiply floating point numbers by
      > powers of two? Conceptually, all you need to do is add to the
      > mantissa. But can I write C code (or x86 assembly) to accomplish this
      > without a full-blown multiply?
      >[/color]
      My advice: don't bother. The chance that you'll beat the combination of FPU
      and compiler is small, and a trick like this tends to break down when you
      least expect it.

      For example, if you want to do this the right way, you have to deal with the
      infinities, denormalized numbers, NaNs and last but not least, zero. But of
      course you can't, since that would make your code far too slow.
      [color=blue]
      > For example, I'd like to be able to do the following very quickly:
      >
      > double x;
      > double y;
      >
      > x = 42.13;
      > y = (1 << 9) * x;
      >[/color]
      Verify that you really need to do this faster than you're doing it now
      first. Then see if there's some way to avoid doing the multiplication
      altogether (at least in tight loops) by changing the way you handle your
      data. Finally, if all these options are exhausted, you'd best go with x86
      assembler and read up on the format of double precision numbers. Try
      comp.lang.asm.x 86. When you're at this point, C (even nonportable C) is
      unlikely to help you enough.

      S.

      Comment

      • Eric Sosman

        #4
        Re: &quot;Shifting& quot; floating point numbers



        woessner@gmail. com wrote On 03/21/06 13:45,:[color=blue]
        > Does anyone know of a fast way to multiply floating point numbers by
        > powers of two? Conceptually, all you need to do is add to the
        > mantissa.[/color]

        ITYM "add the exponent."
        [color=blue]
        > But can I write C code (or x86 assembly) to accomplish this
        > without a full-blown multiply?
        >
        > For example, I'd like to be able to do the following very quickly:
        >
        > double x;
        > double y;
        >
        > x = 42.13;
        > y = (1 << 9) * x;[/color]

        #include <math.h>
        ...
        y = ldexp(x, 9);

        No guarantees about relative speed, though: You'll
        need to measure on the platform(s) of interest.

        --
        Eric.Sosman@sun .com

        Comment

        • Pierre Maurette

          #5
          Re: &quot;Shifting& quot; floating point numbers

          woessner@gmail. com, le 21/03/2006 a écrit :[color=blue]
          > Does anyone know of a fast way to multiply floating point numbers by
          > powers of two? Conceptually, all you need to do is add to the
          > mantissa.[/color]
          Mantissa ? Exponent, no ?
          [color=blue]
          > But can I write C code (or x86 assembly) to accomplish this
          > without a full-blown multiply?[/color]
          [I consider Intel FPU, double / real8]
          A problem is in the position of the exponent in the double. From bit 52
          to bit 62. You can't use this way in order to have faster code, just
          for fun.

          In assembly, you have two ways:

          - FIMUL, multiply a FP data by an integer.

          - FSCALE, that do just what you want, multiply very quickly by a power
          of 2 ;-) You need just to have the power (9, not 2^9 !) in ST(1) and do
          FSCALE.


          --
          Pierre Maurette


          Comment

          • Keith Thompson

            #6
            Re: &quot;Shifting& quot; floating point numbers

            Pierre Maurette <maurettepierre @wanadoo.fr> writes:[color=blue]
            > woessner@gmail. com, le 21/03/2006 a écrit :[color=green]
            >> Does anyone know of a fast way to multiply floating point numbers by
            >> powers of two? Conceptually, all you need to do is add to the
            >> mantissa.[/color]
            > Mantissa ? Exponent, no ?
            >[color=green]
            >> But can I write C code (or x86 assembly) to accomplish this
            >> without a full-blown multiply?[/color]
            > [I consider Intel FPU, double / real8]
            > A problem is in the position of the exponent in the double. From bit
            > 52 to bit 62. You can't use this way in order to have faster code,
            > just for fun.
            >
            > In assembly, you have two ways:
            >
            > - FIMUL, multiply a FP data by an integer.
            >
            > - FSCALE, that do just what you want, multiply very quickly by a power
            > of 2 ;-) You need just to have the power (9, not 2^9 !) in ST(1) and
            > do FSCALE.[/color]

            Please don't post system-specific answers like this here. Most of us
            have no way of knowing whether your description is accurate. I make
            mistakes every now and then; when I make them in a forum full of
            experts on what I'm talking about, they'll be corrected.

            And, of course, it's off-topic. There are newsgroups where such
            things are topical; comp.lang.asm.x 86 is probably one of them.

            --
            Keith Thompson (The_Other_Keit h) kst-u@mib.org <http://www.ghoti.net/~kst>
            San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
            We must do something. This is something. Therefore, we must do this.

            Comment

            • Pierre Maurette

              #7
              Re: &quot;Shifting& quot; floating point numbers

              Keith Thompson, le 21/03/2006 a écrit :
              [...][color=blue]
              > And, of course, it's off-topic. There are newsgroups where such
              > things are topical; comp.lang.asm.x 86 is probably one of them.[/color]
              I agree your remark. But its was an answer to an off-topic question.

              --
              Pierre Maurette


              Comment

              • Keith Thompson

                #8
                Re: &quot;Shifting& quot; floating point numbers

                woessner@gmail. com writes:[color=blue]
                > Does anyone know of a fast way to multiply floating point numbers by
                > powers of two? Conceptually, all you need to do is add to the
                > mantissa. But can I write C code (or x86 assembly) to accomplish this
                > without a full-blown multiply?
                >
                > For example, I'd like to be able to do the following very quickly:
                >
                > double x;
                > double y;
                >
                > x = 42.13;
                > y = (1 << 9) * x;[/color]

                Compile the code with whatever optimization options are appropriate,
                and look at the assembly language. If your compiler generates code
                that uses something other than (and presumably faster than) a
                floating-point multiply, then you're all set; there's no need to do
                source-level optimization if the compiler will do it for you. If the
                compiler emits an ordinary floating-point multiply instruction, then
                it may mean that that's the best way to do the multiplication.

                It's also possible that you can optimize this better than your
                compiler can, but that's not the way to bet (unless you've actually
                measured it).

                And always remember the Rules of Optimization:

                Rule 1: Don't do it.
                Rule 2 (for experts only): Don't do it yet.

                --
                Keith Thompson (The_Other_Keit h) kst-u@mib.org <http://www.ghoti.net/~kst>
                San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
                We must do something. This is something. Therefore, we must do this.

                Comment

                • Jordan Abel

                  #9
                  Re: &quot;Shifting& quot; floating point numbers

                  On 2006-03-21, Pierre Maurette <maurettepierre @wanadoo.fr> wrote:[color=blue]
                  > - FSCALE, that do just what you want, multiply very quickly by a power
                  > of 2 ;-) You need just to have the power (9, not 2^9 !) in ST(1) and do
                  > FSCALE.[/color]

                  This instruction may be available to C as the "scalbn" function (and if
                  not, scalbn will be a software implementation that does the same thing),
                  and I suspect this is exactly what he wants.

                  C99 only, of course.

                  Here's my system's implementation of it for i387

                  RCSID("$FreeBSD : src/lib/msun/i387/s_scalbn.S,v 1.7 1999/08/28 00:06:13 peter Exp $")

                  ENTRY(scalbn)
                  fildl 12(%esp)
                  fldl 4(%esp)
                  fscale
                  fstp %st(1)
                  ret

                  Comment

                  • Jordan Abel

                    #10
                    Re: &quot;Shifting& quot; floating point numbers

                    On 2006-03-21, Pierre Maurette <maurettepierre @wanadoo.fr> wrote:[color=blue]
                    > Keith Thompson, le 21/03/2006 a écrit :
                    > [...][color=green]
                    >> And, of course, it's off-topic. There are newsgroups where such
                    >> things are topical; comp.lang.asm.x 86 is probably one of them.[/color]
                    > I agree your remark. But its was an answer to an off-topic question.[/color]

                    Not really. scalbn() [and its friends] are the on-topic answer.

                    Comment

                    • Jordan Abel

                      #11
                      Re: &quot;Shifting& quot; floating point numbers

                      On 2006-03-21, woessner@gmail. com <woessner@gmail .com> wrote:[color=blue]
                      > Does anyone know of a fast way to multiply floating point numbers by
                      > powers of two? Conceptually, all you need to do is add to the
                      > mantissa. But can I write C code (or x86 assembly) to accomplish this
                      > without a full-blown multiply?
                      >
                      > For example, I'd like to be able to do the following very quickly:
                      >
                      > double x;
                      > double y;
                      >
                      > x = 42.13;
                      > y = (1 << 9) * x;
                      >
                      > Thanks in advance,
                      > Bill[/color]

                      y = scalbn(x,9);

                      Everyone else thinks you're off-topic because no-one else knows about
                      this function, apparently.

                      Comment

                      • Eric Sosman

                        #12
                        Re: &quot;Shifting& quot; floating point numbers



                        Jordan Abel wrote On 03/21/06 15:51,:[color=blue]
                        > On 2006-03-21, woessner@gmail. com <woessner@gmail .com> wrote:
                        >[color=green]
                        >>Does anyone know of a fast way to multiply floating point numbers by
                        >>powers of two? Conceptually, all you need to do is add to the
                        >>mantissa. But can I write C code (or x86 assembly) to accomplish this
                        >>without a full-blown multiply?
                        >>
                        >>For example, I'd like to be able to do the following very quickly:
                        >>
                        >>double x;
                        >>double y;
                        >>
                        >>x = 42.13;
                        >>y = (1 << 9) * x;
                        >>
                        >>Thanks in advance,
                        >>Bill[/color]
                        >
                        >
                        > y = scalbn(x,9);[/color]

                        ITYM:

                        #if FLT_RADIX == 2
                        y = scalbn(x, 9);
                        #else
                        y = ???;
                        #endif

                        I've already posted a candidate for "???", one that
                        eliminates the dependency on C99 and perhaps even
                        obviates the preprocessor gunk ...

                        --
                        Eric.Sosman@sun .com

                        Comment

                        • Keith Thompson

                          #13
                          Re: &quot;Shifting& quot; floating point numbers

                          Pierre Maurette <maurettepierre @wanadoo.fr> writes:[color=blue]
                          > Keith Thompson, le 21/03/2006 a écrit :
                          > [...][color=green]
                          >> And, of course, it's off-topic. There are newsgroups where such
                          >> things are topical; comp.lang.asm.x 86 is probably one of them.[/color]
                          > I agree your remark. But its was an answer to an off-topic question.[/color]

                          The question was partly off-topic. But the solution is simple: don't
                          try to answer off-topic questions; instead, redirect the poster to an
                          appropriate forum. (I sometimes offer a small system-specific hint
                          while doing so, but it's usually no more than a pointer to the
                          answer.)

                          --
                          Keith Thompson (The_Other_Keit h) kst-u@mib.org <http://www.ghoti.net/~kst>
                          San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
                          We must do something. This is something. Therefore, we must do this.

                          Comment

                          • P.J. Plauger

                            #14
                            Re: &quot;Shifting& quot; floating point numbers

                            "Eric Sosman" <Eric.Sosman@su n.com> wrote in message
                            news:dvpk84$9cg $1@news1brm.Cen tral.Sun.COM...
                            [color=blue]
                            > woessner@gmail. com wrote On 03/21/06 13:45,:[color=green]
                            >> Does anyone know of a fast way to multiply floating point numbers by
                            >> powers of two? Conceptually, all you need to do is add to the
                            >> mantissa.[/color]
                            >
                            > ITYM "add the exponent."
                            >[color=green]
                            >> But can I write C code (or x86 assembly) to accomplish this
                            >> without a full-blown multiply?
                            >>
                            >> For example, I'd like to be able to do the following very quickly:
                            >>
                            >> double x;
                            >> double y;
                            >>
                            >> x = 42.13;
                            >> y = (1 << 9) * x;[/color]
                            >
                            > #include <math.h>
                            > ...
                            > y = ldexp(x, 9);
                            >
                            > No guarantees about relative speed, though: You'll
                            > need to measure on the platform(s) of interest.[/color]

                            Before it gets lost in all the noise, this is the right answer.
                            And it's been in the C Standard since C89.

                            P.J. Plauger
                            Dinkumware, Ltd.



                            Comment

                            • Jordan Abel

                              #15
                              Re: &quot;Shifting& quot; floating point numbers

                              On 2006-03-21, P.J. Plauger <pjp@dinkumware .com> wrote:[color=blue]
                              > "Eric Sosman" <Eric.Sosman@su n.com> wrote in message
                              > news:dvpk84$9cg $1@news1brm.Cen tral.Sun.COM...
                              >[color=green]
                              >> woessner@gmail. com wrote On 03/21/06 13:45,:[color=darkred]
                              >>> Does anyone know of a fast way to multiply floating point numbers by
                              >>> powers of two? Conceptually, all you need to do is add to the
                              >>> mantissa.[/color]
                              >>
                              >> ITYM "add the exponent."
                              >>[color=darkred]
                              >>> But can I write C code (or x86 assembly) to accomplish this
                              >>> without a full-blown multiply?
                              >>>
                              >>> For example, I'd like to be able to do the following very quickly:
                              >>>
                              >>> double x;
                              >>> double y;
                              >>>
                              >>> x = 42.13;
                              >>> y = (1 << 9) * x;[/color]
                              >>
                              >> #include <math.h>
                              >> ...
                              >> y = ldexp(x, 9);
                              >>
                              >> No guarantees about relative speed, though: You'll
                              >> need to measure on the platform(s) of interest.[/color]
                              >
                              > Before it gets lost in all the noise, this is the right answer.
                              > And it's been in the C Standard since C89.[/color]

                              I thought that ldexp set the exponent to the number given, i.e. the new
                              exponent would be 9 regardless of the current exponent (i.e. 42.13's
                              exponent is already six) - why is it called "ldexp" (i thought it stood
                              for "load exponent", which only makes sense with my version, not the
                              actual function)

                              Comment

                              Working...