libs/libc/stdio: Add support for %g format which, for these purpose, is equivalent to %f except that trailing zeroes are suppressed.

This commit is contained in:
Gregory Nutt
2019-02-15 11:45:25 -06:00
parent 5739179109
commit 4dc0636f1e
3 changed files with 110 additions and 60 deletions
+3 -3
View File
@@ -120,9 +120,9 @@ config NANO_PRINTF
default n if !DEFAULT_SMALL default n if !DEFAULT_SMALL
depends on !LIBC_LONG_LONG depends on !LIBC_LONG_LONG
---help--- ---help---
Replace printf code with version from newlib-nano. This version Replace printf code with version from newlib-nano. Can be
adds the 'g' format. However, it does not include 'long long' signifcantly smaller, especially if floating support is enabled.
support. However, it does not include 'long long' support.
config NANO_PRINTLEVEL config NANO_PRINTLEVEL
int "Nano printf support level" int "Nano printf support level"
+58 -6
View File
@@ -46,6 +46,7 @@
#include <nuttx/config.h> #include <nuttx/config.h>
#include <stdbool.h>
#include <math.h> #include <math.h>
#include <assert.h> #include <assert.h>
@@ -67,6 +68,23 @@
# define MAX(a,b) (a > b ? a : b) # define MAX(a,b) (a > b ? a : b)
#endif #endif
/* Use (almost) the maximim precision with %g format if no precision is
* specified. We do not use the full precision beause the least significant
* digits are probably garbage.
*
* REVISIT: This should be smarter. 15 digits is the maximum size of the
* number. The maximum precision is really 15 minus the number of digits
* in the integer part.
*/
#define DOUBLE_PRECISON_MAX 13 /* vs 15 which is the maximum */
/* Use a default precision of 6 for the %f format if no precision is
* specified.
*/
#define DEFAULT_PRECISON 6
/**************************************************************************** /****************************************************************************
* Private Functions * Private Functions
****************************************************************************/ ****************************************************************************/
@@ -128,10 +146,11 @@ static void lib_dtoa_string(FAR struct lib_outstream_s *obj, const char *str)
****************************************************************************/ ****************************************************************************/
static void lib_dtoa(FAR struct lib_outstream_s *obj, int fmt, int prec, static void lib_dtoa(FAR struct lib_outstream_s *obj, int fmt, int prec,
uint8_t flags, double value) uint16_t flags, double value)
{ {
FAR char *digits; /* String returned by __dtoa */ FAR char *digits; /* String returned by __dtoa */
FAR char *rve; /* Points to the end of the return value */ FAR char *rve; /* Points to the end of the return value */
bool notrailing; /* True: No trailing zeros */
int expt; /* Integer value of exponent */ int expt; /* Integer value of exponent */
int numlen; /* Actual number of digits returned by cvt */ int numlen; /* Actual number of digits returned by cvt */
int nchars; /* Number of characters to print */ int nchars; /* Number of characters to print */
@@ -149,6 +168,22 @@ static void lib_dtoa(FAR struct lib_outstream_s *obj, int fmt, int prec,
DEBUGASSERT(up_interrupt_context() == false); DEBUGASSERT(up_interrupt_context() == false);
#endif #endif
/* Set to default precision if none specified */
notrailing = false;
if (!IS_HASDOT(flags) && prec == 0)
{
if (IS_NOTRAILINGZERO(flags))
{
prec = DOUBLE_PRECISON_MAX;
notrailing = true;
}
else
{
prec = DEFAULT_PRECISON;
}
}
/* Special handling for NaN and Infinity */ /* Special handling for NaN and Infinity */
if (isnan(value)) if (isnan(value))
@@ -198,7 +233,7 @@ static void lib_dtoa(FAR struct lib_outstream_s *obj, int fmt, int prec,
* the print precision. * the print precision.
*/ */
if (value == 0 || expt < -prec) if (value == 0.0 || (expt < (notrailing ? 0 : -prec)))
{ {
/* kludge for __dtoa irregularity */ /* kludge for __dtoa irregularity */
@@ -208,21 +243,27 @@ static void lib_dtoa(FAR struct lib_outstream_s *obj, int fmt, int prec,
* particular precision is requested. * particular precision is requested.
*/ */
if (prec > 0 || IS_ALTFORM(flags)) if ((prec > 0 && !notrailing) || IS_ALTFORM(flags))
{ {
obj->put(obj, '.'); obj->put(obj, '.');
/* Always print at least one digit to the right of the decimal point. */ /* Always print at least one digit to the right of the decimal point. */
if (notrailing)
{
prec = MAX(1, numlen);
}
else
{
prec = MAX(1, prec); prec = MAX(1, prec);
} }
} }
}
/* A non-zero value will be printed */ /* A non-zero value will be printed */
else else
{ {
/* Handle the case where the value is less than 1.0 (in magnitude) and /* Handle the case where the value is less than 1.0 (in magnitude) and
* will need a leading zero. * will need a leading zero.
*/ */
@@ -239,7 +280,7 @@ static void lib_dtoa(FAR struct lib_outstream_s *obj, int fmt, int prec,
/* Print any leading zeros to the right of the decimal point */ /* Print any leading zeros to the right of the decimal point */
if (expt < 0) if (expt < 0 || !notrailing)
{ {
nchars = MIN(-expt, prec); nchars = MIN(-expt, prec);
zeroes(obj, nchars); zeroes(obj, nchars);
@@ -277,7 +318,8 @@ static void lib_dtoa(FAR struct lib_outstream_s *obj, int fmt, int prec,
* requested. * requested.
*/ */
if (numlen > 0 || prec > 0 || IS_ALTFORM(flags)) if (numlen > 0 || (prec > 0 && !notrailing) ||
IS_ALTFORM(flags))
{ {
/* Print the decimal point */ /* Print the decimal point */
@@ -287,9 +329,16 @@ static void lib_dtoa(FAR struct lib_outstream_s *obj, int fmt, int prec,
* point. * point.
*/ */
if (notrailing)
{
prec = MAX(1, numlen);
}
else
{
prec = MAX(1, prec); prec = MAX(1, prec);
} }
} }
}
/* If a precision was specified, then limit the number digits to the /* If a precision was specified, then limit the number digits to the
* right of the decimal point. * right of the decimal point.
@@ -319,8 +368,11 @@ static void lib_dtoa(FAR struct lib_outstream_s *obj, int fmt, int prec,
/* Finally, print any trailing zeroes */ /* Finally, print any trailing zeroes */
if (!notrailing)
{
zeroes(obj, prec); zeroes(obj, prec);
} }
}
/**************************************************************************** /****************************************************************************
* Public Functions * Public Functions
+44 -46
View File
@@ -53,14 +53,15 @@
* Pre-processor Definitions * Pre-processor Definitions
****************************************************************************/ ****************************************************************************/
#define FLAG_SHOWPLUS 0x01 #define FLAG_SHOWPLUS 0x0001
#define FLAG_ALTFORM 0x02 #define FLAG_ALTFORM 0x0002
#define FLAG_HASDOT 0x04 #define FLAG_HASDOT 0x0004
#define FLAG_HASASTERISKWIDTH 0x08 #define FLAG_HASASTERISKWIDTH 0x0008
#define FLAG_HASASTERISKTRUNC 0x10 #define FLAG_HASASTERISKTRUNC 0x0010
#define FLAG_LONGPRECISION 0x20 #define FLAG_LONGPRECISION 0x0020
#define FLAG_LONGLONGPRECISION 0x40 #define FLAG_LONGLONGPRECISION 0x0040
#define FLAG_NEGATE 0x80 #define FLAG_NEGATE 0x0080
#define FLAG_NOTRAILINGZERO 0x0100
#define SET_SHOWPLUS(f) do (f) |= FLAG_SHOWPLUS; while (0) #define SET_SHOWPLUS(f) do (f) |= FLAG_SHOWPLUS; while (0)
#define SET_ALTFORM(f) do (f) |= FLAG_ALTFORM; while (0) #define SET_ALTFORM(f) do (f) |= FLAG_ALTFORM; while (0)
@@ -70,6 +71,7 @@
#define SET_LONGPRECISION(f) do (f) |= FLAG_LONGPRECISION; while (0) #define SET_LONGPRECISION(f) do (f) |= FLAG_LONGPRECISION; while (0)
#define SET_LONGLONGPRECISION(f) do (f) |= FLAG_LONGLONGPRECISION; while (0) #define SET_LONGLONGPRECISION(f) do (f) |= FLAG_LONGLONGPRECISION; while (0)
#define SET_NEGATE(f) do (f) |= FLAG_NEGATE; while (0) #define SET_NEGATE(f) do (f) |= FLAG_NEGATE; while (0)
#define SET_NOTRAILINGZERO(f) do (f) |= FLAG_NOTRAILINGZERO; while (0)
#define CLR_SHOWPLUS(f) do (f) &= ~FLAG_SHOWPLUS; while (0) #define CLR_SHOWPLUS(f) do (f) &= ~FLAG_SHOWPLUS; while (0)
#define CLR_ALTFORM(f) do (f) &= ~FLAG_ALTFORM; while (0) #define CLR_ALTFORM(f) do (f) &= ~FLAG_ALTFORM; while (0)
@@ -80,6 +82,7 @@
#define CLR_LONGLONGPRECISION(f) do (f) &= ~FLAG_LONGLONGPRECISION; while (0) #define CLR_LONGLONGPRECISION(f) do (f) &= ~FLAG_LONGLONGPRECISION; while (0)
#define CLR_NEGATE(f) do (f) &= ~FLAG_NEGATE; while (0) #define CLR_NEGATE(f) do (f) &= ~FLAG_NEGATE; while (0)
#define CLR_SIGNED(f) do (f) &= ~(FLAG_SHOWPLUS|FLAG_NEGATE); while (0) #define CLR_SIGNED(f) do (f) &= ~(FLAG_SHOWPLUS|FLAG_NEGATE); while (0)
#define CLR_NOTRAILINGZERO(f) do (f) &= ~FLAG_NOTRAILINGZERO; while (0)
#define IS_SHOWPLUS(f) (((f) & FLAG_SHOWPLUS) != 0) #define IS_SHOWPLUS(f) (((f) & FLAG_SHOWPLUS) != 0)
#define IS_ALTFORM(f) (((f) & FLAG_ALTFORM) != 0) #define IS_ALTFORM(f) (((f) & FLAG_ALTFORM) != 0)
@@ -90,6 +93,7 @@
#define IS_LONGLONGPRECISION(f) (((f) & FLAG_LONGLONGPRECISION) != 0) #define IS_LONGLONGPRECISION(f) (((f) & FLAG_LONGLONGPRECISION) != 0)
#define IS_NEGATE(f) (((f) & FLAG_NEGATE) != 0) #define IS_NEGATE(f) (((f) & FLAG_NEGATE) != 0)
#define IS_SIGNED(f) (((f) & (FLAG_SHOWPLUS|FLAG_NEGATE)) != 0) #define IS_SIGNED(f) (((f) & (FLAG_SHOWPLUS|FLAG_NEGATE)) != 0)
#define IS_NOTRAILINGZERO(f) (((f) & FLAG_NOTRAILINGZERO) != 0)
/* If CONFIG_ARCH_ROMGETC is defined, then it is assumed that the format /* If CONFIG_ARCH_ROMGETC is defined, then it is assumed that the format
* string data cannot be accessed by simply de-referencing the format string * string data cannot be accessed by simply de-referencing the format string
@@ -118,10 +122,6 @@
# define FMT_PREV src-- /* Backup to the previous character */ # define FMT_PREV src-- /* Backup to the previous character */
#endif #endif
/* Default precision to use with %f format if no precision is specified. */
#define FLOAT_PRECISION_DEFAULT 6
/**************************************************************************** /****************************************************************************
* Private Type Declarations * Private Type Declarations
****************************************************************************/ ****************************************************************************/
@@ -141,9 +141,9 @@ enum
/* Pointer to ASCII conversion */ /* Pointer to ASCII conversion */
#ifdef CONFIG_PTR_IS_NOT_INT #ifdef CONFIG_PTR_IS_NOT_INT
static void ptohex(FAR struct lib_outstream_s *obj, uint8_t flags, static void ptohex(FAR struct lib_outstream_s *obj, uint16_t flags,
FAR void *p); FAR void *p);
static int getsizesize(uint8_t fmt, uint8_t flags, FAR void *p) static int getsizesize(uint8_t fmt, uint16_t flags, FAR void *p)
#endif /* CONFIG_PTR_IS_NOT_INT */ #endif /* CONFIG_PTR_IS_NOT_INT */
/* Unsigned int to ASCII conversion */ /* Unsigned int to ASCII conversion */
@@ -154,10 +154,10 @@ static void utohex(FAR struct lib_outstream_s *obj, unsigned int n,
static void utooct(FAR struct lib_outstream_s *obj, unsigned int n); static void utooct(FAR struct lib_outstream_s *obj, unsigned int n);
static void utobin(FAR struct lib_outstream_s *obj, unsigned int n); static void utobin(FAR struct lib_outstream_s *obj, unsigned int n);
static void utoascii(FAR struct lib_outstream_s *obj, uint8_t fmt, static void utoascii(FAR struct lib_outstream_s *obj, uint8_t fmt,
uint8_t flags, unsigned int lln); uint16_t flags, unsigned int lln);
static void fixup(uint8_t fmt, FAR uint8_t *flags, int *n); static void fixup(uint8_t fmt, FAR uint16_t *flags, int *n);
static int getusize(uint8_t fmt, uint8_t flags, unsigned int lln); static int getusize(uint8_t fmt, uint16_t flags, unsigned int lln);
/* Unsigned long int to ASCII conversion */ /* Unsigned long int to ASCII conversion */
@@ -168,9 +168,9 @@ static void lutohex(FAR struct lib_outstream_s *obj, unsigned long ln,
static void lutooct(FAR struct lib_outstream_s *obj, unsigned long ln); static void lutooct(FAR struct lib_outstream_s *obj, unsigned long ln);
static void lutobin(FAR struct lib_outstream_s *obj, unsigned long ln); static void lutobin(FAR struct lib_outstream_s *obj, unsigned long ln);
static void lutoascii(FAR struct lib_outstream_s *obj, uint8_t fmt, static void lutoascii(FAR struct lib_outstream_s *obj, uint8_t fmt,
uint8_t flags, unsigned long ln); uint16_t flags, unsigned long ln);
static void lfixup(uint8_t fmt, FAR uint8_t *flags, long *ln); static void lfixup(uint8_t fmt, FAR uint16_t *flags, long *ln);
static int getlusize(uint8_t fmt, FAR uint8_t flags, unsigned long ln); static int getlusize(uint8_t fmt, FAR uint16_t flags, unsigned long ln);
#endif #endif
/* Unsigned long long int to ASCII conversions */ /* Unsigned long long int to ASCII conversions */
@@ -182,17 +182,17 @@ static void llutohex(FAR struct lib_outstream_s *obj, unsigned long long lln,
static void llutooct(FAR struct lib_outstream_s *obj, unsigned long long lln); static void llutooct(FAR struct lib_outstream_s *obj, unsigned long long lln);
static void llutobin(FAR struct lib_outstream_s *obj, unsigned long long lln); static void llutobin(FAR struct lib_outstream_s *obj, unsigned long long lln);
static void llutoascii(FAR struct lib_outstream_s *obj, uint8_t fmt, static void llutoascii(FAR struct lib_outstream_s *obj, uint8_t fmt,
uint8_t flags, unsigned long long lln); uint16_t flags, unsigned long long lln);
static void llfixup(uint8_t fmt, FAR uint8_t *flags, FAR long long *lln); static void llfixup(uint8_t fmt, FAR uint16_t *flags, FAR long long *lln);
static int getllusize(uint8_t fmt, FAR uint8_t flags, static int getllusize(uint8_t fmt, FAR uint16_t flags,
FAR unsigned long long lln); FAR unsigned long long lln);
#endif #endif
static void prejustify(FAR struct lib_outstream_s *obj, uint8_t fmt, static void prejustify(FAR struct lib_outstream_s *obj, uint8_t fmt,
uint8_t justify, uint8_t flags, int fieldwidth, uint8_t justify, uint16_t flags, int fieldwidth,
int valwidth, int trunc); int valwidth, int trunc);
static void postjustify(FAR struct lib_outstream_s *obj, uint8_t justify, static void postjustify(FAR struct lib_outstream_s *obj, uint8_t justify,
uint8_t flags, int fieldwidth, int valwidth, uint16_t flags, int fieldwidth, int valwidth,
int trunc); int trunc);
/**************************************************************************** /****************************************************************************
@@ -216,7 +216,7 @@ static const char g_nullstring[] = "(null)";
****************************************************************************/ ****************************************************************************/
#ifdef CONFIG_PTR_IS_NOT_INT #ifdef CONFIG_PTR_IS_NOT_INT
static void ptohex(FAR struct lib_outstream_s *obj, uint8_t flags, static void ptohex(FAR struct lib_outstream_s *obj, uint16_t flags,
FAR void *p) FAR void *p)
{ {
union union
@@ -257,7 +257,7 @@ static void ptohex(FAR struct lib_outstream_s *obj, uint8_t flags,
* Name: getpsize * Name: getpsize
****************************************************************************/ ****************************************************************************/
static int getpsize(uint8_t flags, FAR void *p) static int getpsize(uint16_t flags, FAR void *p)
{ {
struct lib_outstream_s nulloutstream; struct lib_outstream_s nulloutstream;
lib_nulloutstream(&nulloutstream); lib_nulloutstream(&nulloutstream);
@@ -379,7 +379,7 @@ static void utobin(FAR struct lib_outstream_s *obj, unsigned int n)
****************************************************************************/ ****************************************************************************/
static void utoascii(FAR struct lib_outstream_s *obj, uint8_t fmt, static void utoascii(FAR struct lib_outstream_s *obj, uint8_t fmt,
uint8_t flags, unsigned int n) uint16_t flags, unsigned int n)
{ {
/* Perform the integer conversion according to the format specifier */ /* Perform the integer conversion according to the format specifier */
@@ -455,7 +455,7 @@ static void utoascii(FAR struct lib_outstream_s *obj, uint8_t fmt,
* Name: fixup * Name: fixup
****************************************************************************/ ****************************************************************************/
static void fixup(uint8_t fmt, FAR uint8_t *flags, FAR int *n) static void fixup(uint8_t fmt, FAR uint16_t *flags, FAR int *n)
{ {
/* Perform the integer conversion according to the format specifier */ /* Perform the integer conversion according to the format specifier */
@@ -491,7 +491,7 @@ static void fixup(uint8_t fmt, FAR uint8_t *flags, FAR int *n)
* Name: getusize * Name: getusize
****************************************************************************/ ****************************************************************************/
static int getusize(uint8_t fmt, uint8_t flags, unsigned int n) static int getusize(uint8_t fmt, uint16_t flags, unsigned int n)
{ {
struct lib_outstream_s nulloutstream; struct lib_outstream_s nulloutstream;
lib_nulloutstream(&nulloutstream); lib_nulloutstream(&nulloutstream);
@@ -505,7 +505,7 @@ static int getusize(uint8_t fmt, uint8_t flags, unsigned int n)
****************************************************************************/ ****************************************************************************/
#ifdef CONFIG_LIBC_FLOATINGPOINT #ifdef CONFIG_LIBC_FLOATINGPOINT
static int getdblsize(uint8_t fmt, int trunc, uint8_t flags, double n) static int getdblsize(uint8_t fmt, int trunc, uint16_t flags, double n)
{ {
struct lib_outstream_s nulloutstream; struct lib_outstream_s nulloutstream;
lib_nulloutstream(&nulloutstream); lib_nulloutstream(&nulloutstream);
@@ -628,7 +628,7 @@ static void lutobin(FAR struct lib_outstream_s *obj, unsigned long n)
****************************************************************************/ ****************************************************************************/
static void lutoascii(FAR struct lib_outstream_s *obj, uint8_t fmt, static void lutoascii(FAR struct lib_outstream_s *obj, uint8_t fmt,
uint8_t flags, unsigned long ln) uint16_t flags, unsigned long ln)
{ {
/* Perform the integer conversion according to the format specifier */ /* Perform the integer conversion according to the format specifier */
@@ -699,7 +699,7 @@ static void lutoascii(FAR struct lib_outstream_s *obj, uint8_t fmt,
* Name: lfixup * Name: lfixup
****************************************************************************/ ****************************************************************************/
static void lfixup(uint8_t fmt, FAR uint8_t *flags, FAR long *ln) static void lfixup(uint8_t fmt, FAR uint16_t *flags, FAR long *ln)
{ {
/* Perform the integer conversion according to the format specifier */ /* Perform the integer conversion according to the format specifier */
@@ -735,7 +735,7 @@ static void lfixup(uint8_t fmt, FAR uint8_t *flags, FAR long *ln)
* Name: getlusize * Name: getlusize
****************************************************************************/ ****************************************************************************/
static int getlusize(uint8_t fmt, uint8_t flags, unsigned long ln) static int getlusize(uint8_t fmt, uint16_t flags, unsigned long ln)
{ {
struct lib_outstream_s nulloutstream; struct lib_outstream_s nulloutstream;
lib_nulloutstream(&nulloutstream); lib_nulloutstream(&nulloutstream);
@@ -858,7 +858,7 @@ static void llutobin(FAR struct lib_outstream_s *obj, unsigned long long n)
****************************************************************************/ ****************************************************************************/
static void llutoascii(FAR struct lib_outstream_s *obj, uint8_t fmt, static void llutoascii(FAR struct lib_outstream_s *obj, uint8_t fmt,
uint8_t flags, unsigned long long lln) uint16_t flags, unsigned long long lln)
{ {
/* Perform the integer conversion according to the format specifier */ /* Perform the integer conversion according to the format specifier */
@@ -929,7 +929,7 @@ static void llutoascii(FAR struct lib_outstream_s *obj, uint8_t fmt,
* Name: llfixup * Name: llfixup
****************************************************************************/ ****************************************************************************/
static void llfixup(uint8_t fmt, FAR uint8_t *flags, FAR long long *lln) static void llfixup(uint8_t fmt, FAR uint16_t *flags, FAR long long *lln)
{ {
/* Perform the integer conversion according to the format specifier */ /* Perform the integer conversion according to the format specifier */
@@ -965,7 +965,7 @@ static void llfixup(uint8_t fmt, FAR uint8_t *flags, FAR long long *lln)
* Name: getllusize * Name: getllusize
****************************************************************************/ ****************************************************************************/
static int getllusize(uint8_t fmt, uint8_t flags, unsigned long long lln) static int getllusize(uint8_t fmt, uint16_t flags, unsigned long long lln)
{ {
struct lib_outstream_s nulloutstream; struct lib_outstream_s nulloutstream;
lib_nulloutstream(&nulloutstream); lib_nulloutstream(&nulloutstream);
@@ -981,7 +981,7 @@ static int getllusize(uint8_t fmt, uint8_t flags, unsigned long long lln)
****************************************************************************/ ****************************************************************************/
static void prejustify(FAR struct lib_outstream_s *obj, uint8_t fmt, static void prejustify(FAR struct lib_outstream_s *obj, uint8_t fmt,
uint8_t justify, uint8_t flags, int fieldwidth, uint8_t justify, uint16_t flags, int fieldwidth,
int valwidth, int trunc) int valwidth, int trunc)
{ {
bool althex = (fmt == 'x' || fmt == 'X' || fmt == 'p' || fmt == 'P') bool althex = (fmt == 'x' || fmt == 'X' || fmt == 'p' || fmt == 'P')
@@ -1144,7 +1144,7 @@ static void prejustify(FAR struct lib_outstream_s *obj, uint8_t fmt,
****************************************************************************/ ****************************************************************************/
static void postjustify(FAR struct lib_outstream_s *obj, uint8_t justify, static void postjustify(FAR struct lib_outstream_s *obj, uint8_t justify,
uint8_t flags, int fieldwidth, int valwidth, uint16_t flags, int fieldwidth, int valwidth,
int trunc) int trunc)
{ {
int i; int i;
@@ -1190,13 +1190,13 @@ int lib_vsprintf(FAR struct lib_outstream_s *obj, FAR const IPTR char *src,
va_list ap) va_list ap)
{ {
FAR char *ptmp; FAR char *ptmp;
int width; uint16_t flags;
int trunc;
uint8_t justify; uint8_t justify;
uint8_t flags;
#ifdef CONFIG_ARCH_ROMGETC #ifdef CONFIG_ARCH_ROMGETC
char ch; char ch;
#endif #endif
int width;
int trunc;
for (FMT_TOP; FMT_CHAR; FMT_BOTTOM) for (FMT_TOP; FMT_CHAR; FMT_BOTTOM)
{ {
@@ -1559,11 +1559,9 @@ int lib_vsprintf(FAR struct lib_outstream_s *obj, FAR const IPTR char *src,
double dblval = va_arg(ap, double); double dblval = va_arg(ap, double);
int dblsize; int dblsize;
/* Set to default precision if none specified */ if (FMT_CHAR == 'g' || FMT_CHAR == 'G')
if (!IS_HASDOT(flags) && trunc == 0)
{ {
trunc = FLOAT_PRECISION_DEFAULT; flags |= FLAG_NOTRAILINGZERO;
} }
/* Get the width of the output */ /* Get the width of the output */