Fix more floating point formatting bugs
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@5013 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
parent
495c45d4f6
commit
4346670013
@ -3129,4 +3129,6 @@
|
||||
point numbers (conversions are fine, but presentation was bad). This
|
||||
is a critical bug fix if you use printf or sprintf to deal with floating
|
||||
point numbers.
|
||||
* lib/stdio/lib_libdtoa.c and lib_libvsprintf.c: Correct some floating
|
||||
point options.
|
||||
|
||||
|
@ -48,6 +48,8 @@
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define MAX_PREC 16
|
||||
|
||||
#ifndef MIN
|
||||
# define MIN(a,b) (a < b ? a : b)
|
||||
#endif
|
||||
@ -107,7 +109,20 @@ static void zeroes(FAR struct lib_outstream_s *obj, int nzeroes)
|
||||
*
|
||||
* Description:
|
||||
* This is part of lib_vsprintf(). It handles the floating point formats.
|
||||
* This version supports only the &f (with precision).
|
||||
* This version supports only the %f (with precision). If no precision
|
||||
* was provided in the format, this will use precision == 0 which is
|
||||
* probably not what you want.
|
||||
*
|
||||
* Input Parameters:
|
||||
* obj - The output stream object
|
||||
* fmt - The format character. Not used 'f' is always assumed
|
||||
* prec - The number of digits to the right of the decimal point. If no
|
||||
* precision is provided in the format, this will be zero. And,
|
||||
* unfortunately in this case, it will be treated literally as
|
||||
* a precision of zero.
|
||||
* flags - Only ALTFORM and SHOWPLUS flags are supported. ALTFORM only
|
||||
* applies if prec == 0 which is not supported anyway.
|
||||
* value - The floating point value to convert.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
@ -146,10 +161,10 @@ static void lib_dtoa(FAR struct lib_outstream_s *obj, int fmt, int prec,
|
||||
{
|
||||
obj->put(obj, '-');
|
||||
}
|
||||
|
||||
/* Always print at least one digit to the right of the decimal point. */
|
||||
|
||||
prec = MAX(1, prec);
|
||||
else if (IS_SHOWPLUS(flags))
|
||||
{
|
||||
obj->put(obj, '+');
|
||||
}
|
||||
|
||||
/* Special case exact zero or the case where the number is smaller than
|
||||
* the print precision.
|
||||
@ -160,14 +175,41 @@ static void lib_dtoa(FAR struct lib_outstream_s *obj, int fmt, int prec,
|
||||
/* kludge for __dtoa irregularity */
|
||||
|
||||
obj->put(obj, '0');
|
||||
obj->put(obj, '.');
|
||||
}
|
||||
else if (expt <= 0)
|
||||
|
||||
/* A decimal point is printed only in the alternate form or if a
|
||||
* particular precision is requested.
|
||||
*/
|
||||
|
||||
if (prec > 0 || IS_ALTFORM(flags))
|
||||
{
|
||||
obj->put(obj, '0');
|
||||
obj->put(obj, '.');
|
||||
|
||||
/* Print leading zeros */
|
||||
/* Always print at least one digit to the right of the decimal point. */
|
||||
|
||||
prec = MAX(1, prec);
|
||||
}
|
||||
}
|
||||
|
||||
/* A non-zero value will be printed */
|
||||
|
||||
else
|
||||
{
|
||||
|
||||
/* Handle the case where the value is less than 1.0 (in magnitude) and
|
||||
* will need a leading zero.
|
||||
*/
|
||||
|
||||
if (expt <= 0)
|
||||
{
|
||||
/* Print a single zero to the left of the decimal point */
|
||||
|
||||
obj->put(obj, '0');
|
||||
|
||||
/* Print the decimal point */
|
||||
|
||||
obj->put(obj, '.');
|
||||
|
||||
/* Print any leading zeros to the right of the decimal point */
|
||||
|
||||
if (expt < 0)
|
||||
{
|
||||
@ -175,23 +217,15 @@ static void lib_dtoa(FAR struct lib_outstream_s *obj, int fmt, int prec,
|
||||
zeroes(obj, nchars);
|
||||
prec -= nchars;
|
||||
}
|
||||
|
||||
/* Print the significant digits */
|
||||
|
||||
nchars = MIN(numlen, prec);
|
||||
for (i = nchars; i > 0; i--)
|
||||
{
|
||||
obj->put(obj, *digits);
|
||||
digits++;
|
||||
}
|
||||
|
||||
/* Decremnt to get the number of trailing zeroes to print */
|
||||
/* Handle the general case where the value is greater than 1.0 (in
|
||||
* magnitude).
|
||||
*/
|
||||
|
||||
prec -= nchars;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Print the integer part */
|
||||
/* Print the integer part to the left of the decimal point */
|
||||
|
||||
for (i = expt; i > 0; i--)
|
||||
{
|
||||
@ -199,14 +233,43 @@ static void lib_dtoa(FAR struct lib_outstream_s *obj, int fmt, int prec,
|
||||
digits++;
|
||||
}
|
||||
|
||||
/* Print the decimal place */
|
||||
/* Get the length of the fractional part */
|
||||
|
||||
numlen -= expt;
|
||||
|
||||
/* If there is no fractional part, then a decimal point is printed
|
||||
* only in the alternate form or if a particular precision is
|
||||
* requested.
|
||||
*/
|
||||
|
||||
if (numlen > 0 || prec > 0 || IS_ALTFORM(flags))
|
||||
{
|
||||
/* Print the decimal point */
|
||||
|
||||
obj->put(obj, '.');
|
||||
|
||||
/* Print the decimal */
|
||||
/* Always print at least one digit to the right of the decimal
|
||||
* point.
|
||||
*/
|
||||
|
||||
numlen -= expt;
|
||||
prec = MAX(1, prec);
|
||||
}
|
||||
}
|
||||
|
||||
/* If a precision was specified, then limit the number digits to the
|
||||
* right of the decimal point.
|
||||
*/
|
||||
|
||||
if (prec > 0)
|
||||
{
|
||||
nchars = MIN(numlen, prec);
|
||||
}
|
||||
else
|
||||
{
|
||||
nchars = numlen;
|
||||
}
|
||||
|
||||
/* Print the fractional part to the right of the decimal point */
|
||||
|
||||
for (i = nchars; i > 0; i--)
|
||||
{
|
||||
|
@ -1587,7 +1587,7 @@ int lib_vsprintf(FAR struct lib_outstream_s *obj, FAR const char *src, va_list a
|
||||
|
||||
/* Perform left field justification actions */
|
||||
|
||||
prejustify(obj, fmt, flags, width, dblsize);
|
||||
prejustify(obj, fmt, 0, width, dblsize);
|
||||
|
||||
/* Output the number */
|
||||
|
||||
@ -1595,7 +1595,7 @@ int lib_vsprintf(FAR struct lib_outstream_s *obj, FAR const char *src, va_list a
|
||||
|
||||
/* Perform right field justification actions */
|
||||
|
||||
postjustify(obj, fmt, flags, width, dblsize);
|
||||
postjustify(obj, fmt, 0, width, dblsize);
|
||||
#else
|
||||
/* Output the number with a fixed precision */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user