diff options
author | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2010-05-08 03:10:51 +0000 |
---|---|---|
committer | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2010-05-08 03:10:51 +0000 |
commit | 50b7bdacbd6d4af3bb3128c038e4e0e2cd0d50df (patch) | |
tree | 4ecda8d995277191f4a8545ce758b5cd1cc4b9c5 /nuttx/lib/lib_libdtoa.c | |
parent | 56651d825a6651d0f70ec59d798c5d7f584786d1 (diff) | |
download | px4-nuttx-50b7bdacbd6d4af3bb3128c038e4e0e2cd0d50df.tar.gz px4-nuttx-50b7bdacbd6d4af3bb3128c038e4e0e2cd0d50df.tar.bz2 px4-nuttx-50b7bdacbd6d4af3bb3128c038e4e0e2cd0d50df.zip |
Add floating point support to printf
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@2656 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx/lib/lib_libdtoa.c')
-rwxr-xr-x | nuttx/lib/lib_libdtoa.c | 365 |
1 files changed, 365 insertions, 0 deletions
diff --git a/nuttx/lib/lib_libdtoa.c b/nuttx/lib/lib_libdtoa.c new file mode 100755 index 000000000..1f74247c2 --- /dev/null +++ b/nuttx/lib/lib_libdtoa.c @@ -0,0 +1,365 @@ +/**************************************************************************** + * lib/lib_libdtoa.c + * + * This file was ported to NuttX by Yolande Cates. + * + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Chris Torek. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define MAXEXP 308 + +/**************************************************************************** + * Private Type Declarations + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static char* cvt(double value, int ndigits, int flags, char *sign, + int *decpt, int ch, int *length); +static int exponent(char *p0, int exp, int fmtch); + +/**************************************************************************** + * Global Constant Data + ****************************************************************************/ + +/**************************************************************************** + * Global Variables + ****************************************************************************/ + +/**************************************************************************** + * Private Constant Data + ****************************************************************************/ + +/**************************************************************************** + * Private Variables + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: cvt + ****************************************************************************/ + +static char* cvt(double value, int ndigits, int flags, char *sign, + int *decpt, int ch, int *length) +{ + int mode, dsgn; + char *digits, *bp, *rve; + + if (ch == 'f') + { + mode = 3; /* ndigits after the decimal point */ + } + else + { + /* To obtain ndigits after the decimal point for the 'e' and 'E' + * formats, round to ndigits + 1 significant figures. + */ + + if (ch == 'e' || ch == 'E') + { + ndigits++; + } + mode = 2; /* ndigits significant digits */ + } + + if (value < 0) + { + value = -value; + *sign = '-'; + } + else + { + *sign = '\000'; + } + + digits = __dtoa(value, mode, ndigits, decpt, &dsgn, &rve); + if ((ch != 'g' && ch != 'G') || IS_ALTFORM(flags)) + { + /* Print trailing zeros */ + + bp = digits + ndigits; + if (ch == 'f') + { + if (*digits == '0' && value) + { + *decpt = -ndigits + 1; + } + bp += *decpt; + } + + if (value == 0) + { + /* kludge for __dtoa irregularity */ + + rve = bp; + } + + while (rve < bp) + { + *rve++ = '0'; + } + } + + *length = rve - digits; + return digits; +} + +/**************************************************************************** + * Name: exponent + ****************************************************************************/ + +static int exponent(FAR char *p0, int exp, int fmtch) +{ + FAR char *p; + FAR char *t; + char expbuf[MAXEXP]; + + p = p0; + *p++ = fmtch; + if (exp < 0) + { + exp = -exp; + *p++ = '-'; + } + else + { + *p++ = '+'; + } + + t = expbuf + MAXEXP; + if (exp > 9) + { + do + { + *--t = (exp % 10) + '0'; + } + while ((exp /= 10) > 9); + *--t = exp + '0'; + for (; t < expbuf + MAXEXP; *p++ = *t++); + } + else + { + *p++ = '0'; + *p++ = exp + '0'; + } + return (p - p0); +} + +/**************************************************************************** + * Name: lib_dtoa + * + * Description: + * This is part of lib_vsprintf(). It handles the floating point formats. + * + ****************************************************************************/ + +static void lib_dtoa(FAR struct lib_outstream_s *obj, int ch, int prec, + uint8_t flags, double _double) +{ + FAR char *cp; /* Handy char pointer (short term usage) */ + FAR char *cp_free = NULL; /* BIONIC: copy of cp to be freed after usage */ + char expstr[7]; /* Buffer for exponent string */ + char sign; /* Temporary negative sign for floats */ + int expt; /* Integer value of exponent */ + int expsize = 0; /* Character count for expstr */ + int ndig; /* Actual number of digits returned by cvt */ + int size; /* Size of converted field or string */ + int i; + + cp = cvt(_double, prec, flags, &sign, &expt, ch, &ndig); + cp_free = cp; + + if (ch == 'g' || ch == 'G') + { + /* 'g' or 'G' fmt */ + + if (expt <= -4 || expt > prec) + { + ch = (ch == 'g') ? 'e' : 'E'; + } + else + { + ch = 'g'; + } + } + + if (ch <= 'e') + { + /* 'e' or 'E' fmt */ + + --expt; + expsize = exponent(expstr, expt, ch); + size = expsize + ndig; + if (ndig > 1 || IS_ALTFORM(flags)) + { + ++size; + } + } + else if (ch == 'f') + { + /* f fmt */ + + if (expt > 0) + { + size = expt; + if (prec || IS_ALTFORM(flags)) + { + size += prec + 1; + } + } + else /* "0.X" */ + { + size = prec + 2; + } + } + else if (expt >= ndig) + { + /* fixed g fmt */ + + size = expt; + if (IS_ALTFORM(flags)) + { + ++size; + } + } + else + { + size = ndig + (expt > 0 ? 1 : 2 - expt); + } + + if (sign) + { + obj->put(obj, '-'); + } + + if (_double == 0) + { + /* kludge for __dtoa irregularity */ + + obj->put(obj, '0'); + if (expt < ndig || IS_ALTFORM(flags)) + { + obj->put(obj, '.'); + + i = ndig - 1; + while (i > 0) + { + obj->put(obj, '0'); + i--; + } + } + } + else if (expt <= 0) + { + obj->put(obj, '0'); + obj->put(obj, '.'); + + i = ndig; + while (i > 0) + { + obj->put(obj, *cp); + i--; + cp++; + } + } + else if (expt >= ndig) + { + i = ndig; + while (i > 0) + { + obj->put(obj, *cp); + i--; + cp++; + } + + i = expt - ndig; + while (i > 0) + { + obj->put(obj, '0'); + i--; + } + + if (IS_ALTFORM(flags)) + { + obj->put(obj, '.'); + } + } + else + { + /* print the integer */ + + i = expt; + while (i > 0) + { + obj->put(obj, *cp); + i--; + cp++; + } + + /* print the decimal place */ + + obj->put(obj, '.'); + + /* print the decimal */ + + i = ndig - expt; + while (i > 0) + { + obj->put(obj, *cp); + i--; + cp++; + } + } +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + |