self made pow() c++

I have looked at this paper here which describes how to approximate the exponential function for double precision. After a little research on Wikipedia about single precision floating point representation I have worked out the equivalent algorithms. They only implemented the exp function, so I found an inverse function for the log and then simply did

    POW(a, b) = EXP(LOG(a) * b).

compiling this gcc4.6.2 yields a pow function almost 4 times faster than the standard library’s implementation (compiling with O2).

Note: the code for EXP is copied almost verbatim from the paper I read and the LOG function is copied from here.

Here is the relevant code:

    #define EXP_A 184
    #define EXP_C 16249 

    float EXP(float y)
    {
      union
      {
        float d;
        struct
        {
    #ifdef LITTLE_ENDIAN
          short j, i;
    #else
          short i, j;
    #endif
        } n;
      } eco;
      eco.n.i = EXP_A*(y) + (EXP_C);
      eco.n.j = 0;
      return eco.d;
    }

    float LOG(float y)
    {
      int * nTemp = (int*)&y;
      y = (*nTemp) >> 16;
      return (y - EXP_C) / EXP_A;
    }

    float POW(float b, float p)
    {
      return EXP(LOG(b) * p);
    }

There is still some optimization you can do here, or perhaps that is good enough.
This is a rough approximation but if you would have been satisfied with the errors introduced using the double representation, I imagine this will be satisfactory.

Leave a Comment