diff --git a/src/math.c b/src/math.c index 17277d8..d87564f 100644 --- a/src/math.c +++ b/src/math.c @@ -168,7 +168,7 @@ if (x < 0) { - neg = 1; + neg = true; x = -x; } @@ -191,33 +191,70 @@ rv *= e; } + float rv_frac = 1; if (x > 0) { - float rv_frac = 1; - - for(uint32_t i = 8; i > 0; i--) - rv_frac = 1 + x * rv_frac / (float)i; + float f = x; - if (neg) - return 1 / (rv * rv_frac); - else - return rv * rv_frac; + for(uint32_t i = 2; i < 8; i++) + { + rv_frac += f; + f *= x / (float)i; + } } if (neg) - return 1 / rv; + return 1 / (rv * rv_frac); else - return rv; + return rv * rv_frac; } double exp(double x) { + bool neg = false; + if (x < 0) + { + neg = true; + x = -x; + } + double rv; + + uint32_t x_int = x; + x -= x_int; + if (x_int > 1023) + { + return INFINITY; + } + else + { + rv = 1; + double e = M_E; + for(uint32_t i = 0; (i < 10) && x_int; i++, x_int >>= 1, e *= e) + if (x_int & 0x01) + rv *= e; + } + + double rv_frac = 1; + if (x > 0) + { + double f = x; + for(uint32_t i = 2; i < 16; i++) + { + rv_frac += f; + f *= x / (double)i; + } + } + + if (neg) + return 1 / (rv * rv_frac); + else + return rv * rv_frac; }