diff options
author | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2012-10-28 18:42:09 +0000 |
---|---|---|
committer | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2012-10-28 18:42:09 +0000 |
commit | 2e745de2f7768f4932e365f0a49edbe15a448818 (patch) | |
tree | 73b8411e1d00ef6df3dd5fa2ed717241174ae14b /nuttx/lib/math/lib_exp.c | |
parent | 83edd56f6581555c199f3cc3a96ed80f58554c1a (diff) | |
download | px4-nuttx-2e745de2f7768f4932e365f0a49edbe15a448818.tar.gz px4-nuttx-2e745de2f7768f4932e365f0a49edbe15a448818.tar.bz2 px4-nuttx-2e745de2f7768f4932e365f0a49edbe15a448818.zip |
lib/math files not follow coding standard; float, double, and long double versions in separate files to reduce size of dumb link
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@5270 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx/lib/math/lib_exp.c')
-rw-r--r-- | nuttx/lib/math/lib_exp.c | 346 |
1 files changed, 109 insertions, 237 deletions
diff --git a/nuttx/lib/math/lib_exp.c b/nuttx/lib/math/lib_exp.c index a70cb10e7..5b54dbaac 100644 --- a/nuttx/lib/math/lib_exp.c +++ b/nuttx/lib/math/lib_exp.c @@ -1,4 +1,14 @@ -/* +/************************************************************************ + * lib/math/lib_exp.c + * + * This file is a part of NuttX: + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Ported by: Darcy Gong + * + * It derives from the Rhombs OS math library by Nick Johnson which has + * a compatibile, MIT-style license: + * * Copyright (C) 2009-2011 Nick Johnson <nickbjohnson4224 at gmail.com> * * Permission to use, copy, modify, and distribute this software for any @@ -12,242 +22,104 @@ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <apps/math.h> -#include <float.h> -#include <stdint.h> -#include <stdbool.h> -#include <unistd.h> - -#define M_E2 (M_E * M_E) -#define M_E4 (M_E2 * M_E2) -#define M_E8 (M_E4 * M_E4) -#define M_E16 (M_E8 * M_E8) -#define M_E32 (M_E16 * M_E16) -#define M_E64 (M_E32 * M_E32) -#define M_E128 (M_E64 * M_E64) -#define M_E256 (M_E128 * M_E128) -#define M_E512 (M_E256 * M_E256) -#define M_E1024 (M_E512 * M_E512) - -static double _expi_square_tbl[11] = { - M_E, // e^1 - M_E2, // e^2 - M_E4, // e^4 - M_E8, // e^8 - M_E16, // e^16 - M_E32, // e^32 - M_E64, // e^64 - M_E128, // e^128 - M_E256, // e^256 - M_E512, // e^512 - M_E1024, // e^1024 + * + ************************************************************************/ + +/************************************************************************ + * Included Files + ************************************************************************/ + +#include <nuttx/config.h> +#include <nuttx/compiler.h> + +#include <math.h> + +#include "lib_internal.h" + +#if CONFIG_HAVE_DOUBLE + +/************************************************************************ + * Private Data + ************************************************************************/ + +static double _dbl_inv_fact[] = +{ + 1.0 / 1.0, // 1 / 0! + 1.0 / 1.0, // 1 / 1! + 1.0 / 2.0, // 1 / 2! + 1.0 / 6.0, // 1 / 3! + 1.0 / 24.0, // 1 / 4! + 1.0 / 120.0, // 1 / 5! + 1.0 / 720.0, // 1 / 6! + 1.0 / 5040.0, // 1 / 7! + 1.0 / 40320.0, // 1 / 8! + 1.0 / 362880.0, // 1 / 9! + 1.0 / 3628800.0, // 1 / 10! + 1.0 / 39916800.0, // 1 / 11! + 1.0 / 479001600.0, // 1 / 12! + 1.0 / 6227020800.0, // 1 / 13! + 1.0 / 87178291200.0, // 1 / 14! + 1.0 / 1307674368000.0, // 1 / 15! + 1.0 / 20922789888000.0, // 1 / 16! + 1.0 / 355687428096000.0, // 1 / 17! + 1.0 / 6402373705728000.0, // 1 / 18! }; -static double _expi(size_t n) { - size_t i; - double val; - - if (n > 1024) { - return INFINITY; - } - - val = 1.0; - - for (i = 0; n; i++) { - if (n & (1 << i)) { - n &= ~(1 << i); - val *= _expi_square_tbl[i]; - } - } - - return val; -} - -static float _flt_inv_fact[] = { - 1.0 / 1.0, // 1/0! - 1.0 / 1.0, // 1/1! - 1.0 / 2.0, // 1/2! - 1.0 / 6.0, // 1/3! - 1.0 / 24.0, // 1/4! - 1.0 / 120.0, // 1/5! - 1.0 / 720.0, // 1/6! - 1.0 / 5040.0, // 1/7! - 1.0 / 40320.0, // 1/8! - 1.0 / 362880.0, // 1/9! - 1.0 / 3628800.0, // 1/10! -}; - -float expf(float x) { - size_t int_part; - bool invert; - float value; - float x0; - size_t i; - - if (x == 0) { - return 1; - } - else if (x < 0) { - invert = true; - x = -x; - } - else { - invert = false; - } - - /* extract integer component */ - int_part = (size_t) x; - - /* set x to fractional component */ - x -= (float) int_part; - - /* perform Taylor series approximation with eleven terms */ - value = 0.0; - x0 = 1.0; - for (i = 0; i < 10; i++) { - value += x0 * _flt_inv_fact[i]; - x0 *= x; - } - - /* multiply by exp of the integer component */ - value *= _expi(int_part); - - if (invert) { - return (1.0 / value); - } - else { - return value; - } -} - -static double _dbl_inv_fact[] = { - 1.0 / 1.0, // 1 / 0! - 1.0 / 1.0, // 1 / 1! - 1.0 / 2.0, // 1 / 2! - 1.0 / 6.0, // 1 / 3! - 1.0 / 24.0, // 1 / 4! - 1.0 / 120.0, // 1 / 5! - 1.0 / 720.0, // 1 / 6! - 1.0 / 5040.0, // 1 / 7! - 1.0 / 40320.0, // 1 / 8! - 1.0 / 362880.0, // 1 / 9! - 1.0 / 3628800.0, // 1 / 10! - 1.0 / 39916800.0, // 1 / 11! - 1.0 / 479001600.0, // 1 / 12! - 1.0 / 6227020800.0, // 1 / 13! - 1.0 / 87178291200.0, // 1 / 14! - 1.0 / 1307674368000.0, // 1 / 15! - 1.0 / 20922789888000.0, // 1 / 16! - 1.0 / 355687428096000.0, // 1 / 17! - 1.0 / 6402373705728000.0, // 1 / 18! -}; - -double exp(double x) { - size_t int_part; - bool invert; - double value; - double x0; - size_t i; - - if (x == 0) { - return 1; - } - else if (x < 0) { - invert = true; - x = -x; - } - else { - invert = false; - } - - /* extract integer component */ - int_part = (size_t) x; - - /* set x to fractional component */ - x -= (double) int_part; - - /* perform Taylor series approximation with nineteen terms */ - value = 0.0; - x0 = 1.0; - for (i = 0; i < 19; i++) { - value += x0 * _dbl_inv_fact[i]; - x0 *= x; - } - - /* multiply by exp of the integer component */ - value *= _expi(int_part); - - if (invert) { - return (1.0 / value); - } - else { - return value; - } -} - -static long double _ldbl_inv_fact[] = { - 1.0 / 1.0, // 1 / 0! - 1.0 / 1.0, // 1 / 1! - 1.0 / 2.0, // 1 / 2! - 1.0 / 6.0, // 1 / 3! - 1.0 / 24.0, // 1 / 4! - 1.0 / 120.0, // 1 / 5! - 1.0 / 720.0, // 1 / 6! - 1.0 / 5040.0, // 1 / 7! - 1.0 / 40320.0, // 1 / 8! - 1.0 / 362880.0, // 1 / 9! - 1.0 / 3628800.0, // 1 / 10! - 1.0 / 39916800.0, // 1 / 11! - 1.0 / 479001600.0, // 1 / 12! - 1.0 / 6227020800.0, // 1 / 13! - 1.0 / 87178291200.0, // 1 / 14! - 1.0 / 1307674368000.0, // 1 / 15! - 1.0 / 20922789888000.0, // 1 / 16! - 1.0 / 355687428096000.0, // 1 / 17! - 1.0 / 6402373705728000.0, // 1 / 18! -}; - -long double expl(long double x) { - size_t int_part; - bool invert; - long double value; - long double x0; - size_t i; - - if (x == 0) { - return 1; - } - else if (x < 0) { - invert = true; - x = -x; - } - else { - invert = false; - } - - /* extract integer component */ - int_part = (size_t) x; - - /* set x to fractional component */ - x -= (long double) int_part; - - /* perform Taylor series approximation with nineteen terms */ - value = 0.0; - x0 = 1.0; - for (i = 0; i < 19; i++) { - value += x0 * _ldbl_inv_fact[i]; - x0 *= x; - } - - /* multiply by exp of the integer component */ - value *= _expi(int_part); - - if (invert) { - return (1.0 / value); - } - else { - return value; - } +/************************************************************************ + * Public Functions + ************************************************************************/ + +double exp(double x) +{ + size_t int_part; + bool invert; + double value; + double x0; + size_t i; + + if (x == 0) + { + return 1; + } + else if (x < 0) + { + invert = true; + x = -x; + } + else + { + invert = false; + } + + /* Extract integer component */ + + int_part = (size_t) x; + + /* Set x to fractional component */ + + x -= (double)int_part; + + /* Perform Taylor series approximation with nineteen terms */ + + value = 0.0; + x0 = 1.0; + for (i = 0; i < 19; i++) + { + value += x0 * _dbl_inv_fact[i]; + x0 *= x; + } + + /* Multiply by exp of the integer component */ + + value *= lib_expi(int_part); + + if (invert) + { + return (1.0 / value); + } + else + { + return value; + } } +#endif |