Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>I have looked at this paper <a href="http://nic.schraudolph.org/pubs/Schraudolph99.pdf" rel="noreferrer">here</a> 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</p> <pre><code> POW(a, b) = EXP(LOG(a) * b). </code></pre> <p>compiling this gcc4.6.2 yields a pow function almost 4 times faster than the standard library's implementation (compiling with O2).</p> <p>Note: the code for EXP is copied almost verbatim from the paper I read and the LOG function is copied from <a href="http://martin.ankerl.com/2007/10/04/optimized-pow-approximation-for-java-and-c-c/" rel="noreferrer">here</a>.</p> <p>Here is the relevant code:</p> <pre><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*)&amp;y; y = (*nTemp) &gt;&gt; 16; return (y - EXP_C) / EXP_A; } float POW(float b, float p) { return EXP(LOG(b) * p); } </code></pre> <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.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload