Make printf trim trailing zeroes with %[Gg] format

This commit is contained in:
JackMacWindows 2021-05-28 18:11:27 -04:00 committed by GitHub
parent 1996a21e3a
commit da964fa63c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -99,6 +99,7 @@
#define FLAGS_LONG_LONG (1U << 9U) #define FLAGS_LONG_LONG (1U << 9U)
#define FLAGS_PRECISION (1U << 10U) #define FLAGS_PRECISION (1U << 10U)
#define FLAGS_ADAPT_EXP (1U << 11U) #define FLAGS_ADAPT_EXP (1U << 11U)
#define FLAGS_TRIM_ZERO (1U << 12U)
// import float.h for DBL_MAX // import float.h for DBL_MAX
#if PICO_PRINTF_SUPPORT_FLOAT #if PICO_PRINTF_SUPPORT_FLOAT
@ -380,7 +381,7 @@ static size_t _ftoa(out_fct_type out, char *buffer, size_t idx, size_t maxlen, d
} }
// limit precision to 9, cause a prec >= 10 can lead to overflow errors // limit precision to 9, cause a prec >= 10 can lead to overflow errors
while ((len < PICO_PRINTF_FTOA_BUFFER_SIZE) && (prec > 9U)) { while ((len < PICO_PRINTF_FTOA_BUFFER_SIZE) && (prec > 9U)) {
buf[len++] = '0'; if (!(flags & FLAGS_TRIM_ZERO)) buf[len++] = '0';
prec--; prec--;
} }
@ -411,21 +412,30 @@ static size_t _ftoa(out_fct_type out, char *buffer, size_t idx, size_t maxlen, d
} }
} else { } else {
unsigned int count = prec; unsigned int count = prec;
bool nonzero = false;
// now do fractional part, as an unsigned number // now do fractional part, as an unsigned number
while (len < PICO_PRINTF_FTOA_BUFFER_SIZE) { while (len < PICO_PRINTF_FTOA_BUFFER_SIZE) {
--count; --count;
buf[len++] = (char) (48U + (frac % 10U)); char digit = (frac % 10U);
// only print the digit if trimming isn't desired,
// a non-zero digit has already been printed, or it's non-zero
if (!(flags & FLAGS_TRIM_ZERO) || nonzero || digit != 0) {
buf[len++] = (char) (48U + digit);
nonzero = true;
}
if (!(frac /= 10U)) { if (!(frac /= 10U)) {
break; break;
} }
} }
// add extra 0s if (!(flags & FLAGS_TRIM_ZERO) || nonzero) {
while ((len < PICO_PRINTF_FTOA_BUFFER_SIZE) && (count-- > 0U)) { // add extra 0s
buf[len++] = '0'; while ((len < PICO_PRINTF_FTOA_BUFFER_SIZE) && (count-- > 0U)) {
} buf[len++] = '0';
if (len < PICO_PRINTF_FTOA_BUFFER_SIZE) { }
// add decimal if (len < PICO_PRINTF_FTOA_BUFFER_SIZE) {
buf[len++] = '.'; // add decimal
buf[len++] = '.';
}
} }
} }
@ -797,7 +807,7 @@ static int _vsnprintf(out_fct_type out, char *buffer, const size_t maxlen, const
case 'g': case 'g':
case 'G': case 'G':
#if PICO_PRINTF_SUPPORT_FLOAT && PICO_PRINTF_SUPPORT_EXPONENTIAL #if PICO_PRINTF_SUPPORT_FLOAT && PICO_PRINTF_SUPPORT_EXPONENTIAL
if ((*format == 'g') || (*format == 'G')) flags |= FLAGS_ADAPT_EXP; if ((*format == 'g') || (*format == 'G')) flags |= FLAGS_ADAPT_EXP | FLAGS_TRIM_ZERO;
if ((*format == 'E') || (*format == 'G')) flags |= FLAGS_UPPERCASE; if ((*format == 'E') || (*format == 'G')) flags |= FLAGS_UPPERCASE;
idx = _etoa(out, buffer, idx, maxlen, va_arg(va, double), precision, width, flags); idx = _etoa(out, buffer, idx, maxlen, va_arg(va, double), precision, width, flags);
#else #else