Add floating point support to printf
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@2656 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
parent
529b0ba053
commit
2840124ed7
9
COPYING
9
COPYING
@ -3,7 +3,7 @@
|
||||
* COPYING -- Describes the terms under which Nuttx is distributed. A *
|
||||
* copy of the BSD-style licensing is included in this file. In my *
|
||||
* words -- I believe that you should free to use NuttX in any *
|
||||
* environmnet, private, private, commercial, open, closed, etc. *
|
||||
* environment, private, private, commercial, open, closed, etc. *
|
||||
* provided only that you repect the modest copyright notices as *
|
||||
* described in license (below). Please feel free to contact me if you *
|
||||
* have any licensing concerns. *
|
||||
@ -42,3 +42,10 @@
|
||||
* *
|
||||
*************************************************************************/
|
||||
|
||||
If you enable floating point conversions with CONFIG_LIBC_FLOATINGPOINT,
|
||||
then some files with an unmodified BSD license will be included. That
|
||||
license is similar to the above (modified) BSD license, but has an
|
||||
additional requirement that I state the following:
|
||||
|
||||
"This product includes software developed by the University of
|
||||
California, Berkeley and its contributors."
|
||||
|
@ -1114,4 +1114,9 @@
|
||||
LM3S6965
|
||||
* configs/lm3s6965-ek - Add configuration for Stellaris LM3S6965
|
||||
Evaluation Kit.
|
||||
* lib/lib_dtoa.c and lib/lib_dtoa.c - printf will not printf floating
|
||||
point values if you select CONFIG_LIBC_FLOATINGPOINT in your
|
||||
configuration file. Contributed by Yolande Cates. NOTE: these
|
||||
floating point operations have not been well tested and may not
|
||||
be portable to all floating point implementations.
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
<tr align="center" bgcolor="#e4e4e4">
|
||||
<td>
|
||||
<h1><big><font color="#3c34ec"><i>NuttX RTOS</i></font></big></h1>
|
||||
<p>Last Updated: May 6, 2010</p>
|
||||
<p>Last Updated: May 7, 2010</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
@ -1722,6 +1722,11 @@ nuttx-5.5 2010-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
LM3S6965
|
||||
* configs/lm3s6965-ek - Add configuration for Stellaris LM3S6965
|
||||
Evaluation Kit.
|
||||
* lib/lib_dtoa.c and lib/lib_dtoa.c - printf will not printf floating
|
||||
point values if you select CONFIG_LIBC_FLOATINGPOINT in your
|
||||
configuration file. Contributed by Yolande Cates. NOTE: these
|
||||
floating point operations have not been well tested and may not
|
||||
be portable to all floating point implementations.
|
||||
|
||||
pascal-2.1 2010-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
############################################################################
|
||||
# lib/Makefile
|
||||
#
|
||||
# Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
|
||||
# Copyright (C) 2007-2010 Gregory Nutt. All rights reserved.
|
||||
# Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
@ -71,6 +71,9 @@ STDIO_SRCS += lib_fopen.c lib_fclose.c lib_fread.c lib_libfread.c lib_fseek.c \
|
||||
lib_fprintf.c lib_vfprintf.c lib_stdinstream.c lib_stdoutstream.c
|
||||
endif
|
||||
endif
|
||||
ifeq ($(CONFIG_LIBC_FLOATINGPOINT),y)
|
||||
STDIO_SRCS += lib_dtoa.c
|
||||
endif
|
||||
|
||||
STDLIB_SRCS = lib_rand.c lib_qsort.c
|
||||
|
||||
|
1536
lib/lib_dtoa.c
Executable file
1536
lib/lib_dtoa.c
Executable file
File diff suppressed because it is too large
Load Diff
@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* lib/lib_internal.h
|
||||
*
|
||||
* Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2007-2010 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -102,6 +102,13 @@ extern int lib_rawvprintf(const char *src, va_list ap);
|
||||
|
||||
extern int lib_lowvprintf(const char *src, va_list ap);
|
||||
|
||||
/* Defined in lib_dtoa.c */
|
||||
|
||||
#ifdef CONFIG_LIBC_FLOATINGPOINT
|
||||
extern char *__dtoa(double d, int mode, int ndigits,
|
||||
int *decpt, int *sign, char **rve);
|
||||
#endif
|
||||
|
||||
/* Defined in lib_libwrite.c */
|
||||
|
||||
extern ssize_t lib_fwrite(FAR const void *ptr, size_t count, FAR FILE *stream);
|
||||
|
365
lib/lib_libdtoa.c
Executable file
365
lib/lib_libdtoa.c
Executable file
@ -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
|
||||
****************************************************************************/
|
||||
|
@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* lib/lib_libvsprintf.c
|
||||
*
|
||||
* Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2007-2010 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -186,6 +186,12 @@ static const char g_nullstring[] = "(null)";
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/* Include floating point functions */
|
||||
|
||||
#ifdef CONFIG_LIBC_FLOATINGPOINT
|
||||
# include "lib_libdtoa.c"
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ptohex
|
||||
****************************************************************************/
|
||||
@ -1468,9 +1474,8 @@ int lib_vsprintf(FAR struct lib_outstream_s *obj, const char *src, va_list ap)
|
||||
#ifdef CONFIG_LIBC_FLOATINGPOINT
|
||||
else if (strchr("eEfgG", *src))
|
||||
{
|
||||
#ifdef CONFIG_CPP_HAVE_WARNING
|
||||
# warning "No floating point support"
|
||||
#endif
|
||||
double dblval = va_arg(ap, double);
|
||||
lib_dtoa(obj, *src, trunc, flags, dblval);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user