From 19486427580476d3a27df7b050626a5e2161eb78 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Wed, 25 Sep 2013 20:46:13 -0500 Subject: [PATCH] Add Printf extension %H - This conversion has behavior similar to %g: It automatically behaves like %f or %e based on the number of output characters. However, unlike %g, this decision is also based on what will produce the smallest string without truncating the output. The precision field (the * in %.*f) is ignored. Converting a double to text with %H and then back to a double should be lossless. --- src/zstrformat.cpp | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/src/zstrformat.cpp b/src/zstrformat.cpp index c048595ab..7433dd574 100644 --- a/src/zstrformat.cpp +++ b/src/zstrformat.cpp @@ -638,6 +638,12 @@ namespace StringFormat } goto fp_begin; } + else if (type == 'H') + { // %H is an extension that behaves similarly to %g, except it automatically + // selects precision based on whatever will produce the smallest string. + expchar = 'e'; + goto fp_begin; + } #if 0 // The hdtoa function provided with FreeBSD uses a hexadecimal FP constant. // Microsoft's compiler does not support these, so I would need to hack it @@ -690,7 +696,7 @@ fp_begin: precision = DEFPREC; } dblarg = va_arg(arglist, double); - obuff = dtoaresult = dtoa(dblarg, expchar ? 2 : 3, precision, &expt, &signflag, &dtoaend); + obuff = dtoaresult = dtoa(dblarg, type != 'H' ? (expchar ? 2 : 3) : 0, precision, &expt, &signflag, &dtoaend); //fp_common: decimal_point = localeconv()->decimal_point; flags |= F_SIGNED; @@ -742,6 +748,22 @@ fp_begin: } } } + else if (type == 'H') + { + if (expt > -(ndig + 2) && expt <= (ndig + 4)) + { // Make %H smell like %f + expchar = '\0'; + precision = ndig - expt; + if (precision < 0) + { + precision = 0; + } + } + else + {// Make %H smell like %e + precision = ndig; + } + } if (expchar) { expsize = exponent(expstr, expt - 1, expchar);