6565#endif
6666
6767// support for exponential floating point notation (%e/%g)
68+ // default: activated
6869#ifndef PRINTF_DISABLE_SUPPORT_EXPONENTIAL
6970#define PRINTF_SUPPORT_EXPONENTIAL
7071#endif
7172
7273// define the default floating point precision
74+ // default: 6 digits
7375#ifndef PRINTF_DEFAULT_FLOAT_PRECISION
7476#define PRINTF_DEFAULT_FLOAT_PRECISION 6U
7577#endif
7678
7779// define the largest float suitable to print with %f
80+ // default: 1e9
7881#ifndef PRINTF_MAX_FLOAT
7982#define PRINTF_MAX_FLOAT 1e9
8083#endif
@@ -185,11 +188,12 @@ static unsigned int _atoi(const char** str)
185188 return i ;
186189}
187190
191+
188192// output the specified string in reverse, taking care of any zero-padding
189193static size_t _out_rev (out_fct_type out , char * buffer , size_t idx , size_t maxlen , const char * buf , size_t len , unsigned int width , unsigned int flags )
190194{
191195 const size_t start_idx = idx ;
192-
196+
193197 // pad spaces up to given width
194198 if (!(flags & FLAGS_LEFT ) && !(flags & FLAGS_ZEROPAD )) {
195199 for (size_t i = len ; i < width ; i ++ ) {
@@ -198,18 +202,21 @@ static size_t _out_rev(out_fct_type out, char* buffer, size_t idx, size_t maxlen
198202 }
199203
200204 // reverse string
201- while (len ) out (buf [-- len ], buffer , idx ++ , maxlen );
205+ while (len ) {
206+ out (buf [-- len ], buffer , idx ++ , maxlen );
207+ }
202208
203209 // append pad spaces up to given width
204210 if (flags & FLAGS_LEFT ) {
205211 while (idx - start_idx < width ) {
206212 out (' ' , buffer , idx ++ , maxlen );
207213 }
208214 }
209-
215+
210216 return idx ;
211217}
212218
219+
213220// internal itoa format
214221static size_t _ntoa_format (out_fct_type out , char * buffer , size_t idx , size_t maxlen , char * buf , size_t len , bool negative , unsigned int base , unsigned int prec , unsigned int width , unsigned int flags )
215222{
@@ -321,6 +328,7 @@ static size_t _ntoa_long_long(out_fct_type out, char* buffer, size_t idx, size_t
321328static size_t _etoa (out_fct_type out , char * buffer , size_t idx , size_t maxlen , double value , unsigned int prec , unsigned int width , unsigned int flags );
322329#endif
323330
331+
324332// internal ftoa for fixed decimal floating point
325333static size_t _ftoa (out_fct_type out , char * buffer , size_t idx , size_t maxlen , double value , unsigned int prec , unsigned int width , unsigned int flags )
326334{
@@ -341,7 +349,7 @@ static size_t _ftoa(out_fct_type out, char* buffer, size_t idx, size_t maxlen, d
341349
342350 // test for very large values
343351 // standard printf behavior is to print EVERY whole number digit -- which could be 100s of characters overflowing your buffers == bad
344- if ((value > PRINTF_MAX_FLOAT )|| (value < - PRINTF_MAX_FLOAT )) {
352+ if ((value > PRINTF_MAX_FLOAT ) || (value < - PRINTF_MAX_FLOAT )) {
345353#if defined(PRINTF_SUPPORT_EXPONENTIAL )
346354 return _etoa (out , buffer , idx , maxlen , value , prec , width , flags );
347355#else
@@ -447,70 +455,78 @@ static size_t _ftoa(out_fct_type out, char* buffer, size_t idx, size_t maxlen, d
447455 return _out_rev (out , buffer , idx , maxlen , buf , len , width , flags );
448456}
449457
458+
450459#if defined(PRINTF_SUPPORT_EXPONENTIAL )
451- // internal ftoa variant for exponential floating-point type
452- // contributed by Martijn Jasperse <m.jasperse@gmail.com>
460+ // internal ftoa variant for exponential floating-point type, contributed by Martijn Jasperse <m.jasperse@gmail.com>
453461static size_t _etoa (out_fct_type out , char * buffer , size_t idx , size_t maxlen , double value , unsigned int prec , unsigned int width , unsigned int flags )
454462{
455- // check for special values
456- if ((value != value )|| (value > DBL_MAX )|| (value < - DBL_MAX ))
463+ // check for NaN and special values
464+ if ((value != value ) || (value > DBL_MAX ) || (value < - DBL_MAX )) {
457465 return _ftoa (out , buffer , idx , maxlen , value , prec , width , flags );
458-
466+ }
467+
459468 // determine the sign
460- bool negative = value < 0 ;
461- if (negative ) value = - value ;
469+ const bool negative = value < 0 ;
470+ if (negative ) {
471+ value = - value ;
472+ }
462473
463474 // default precision
464475 if (!(flags & FLAGS_PRECISION )) {
465476 prec = PRINTF_DEFAULT_FLOAT_PRECISION ;
466477 }
467-
478+
468479 // determine the decimal exponent
469480 // based on the algorithm by David Gay (https://www.ampl.com/netlib/fp/dtoa.c)
470481 union {
471482 uint64_t U ;
472- double F ;
483+ double F ;
473484 } conv ;
485+
474486 conv .F = value ;
475- int exp2 = (int )((conv .U >> 52 ) & 0x07FF ) - 1023 ; // effectively log2
476- conv .U = (conv .U & ((1ULL << 52 ) - 1 )) | (1023ULL << 52 ); // drop the exponent so conv.F is now in [1,2)
487+ int exp2 = (int )((conv .U >> 52U ) & 0x07FFU ) - 1023 ; // effectively log2
488+ conv .U = (conv .U & ((1ULL << 52U ) - 1U )) | (1023ULL << 52U ); // drop the exponent so conv.F is now in [1,2)
477489 // now approximate log10 from the log2 integer part and an expansion of ln around 1.5
478- int expval = (int )(0.1760912590558 + exp2 * 0.301029995663981 + (conv .F - 1.5 )* 0.289529654602168 );
490+ int expval = (int )(0.1760912590558 + exp2 * 0.301029995663981 + (conv .F - 1.5 ) * 0.289529654602168 );
479491 // now we want to compute 10^expval but we want to be sure it won't overflow
480- exp2 = (int )(expval * 3.321928094887362 + 0.5 );
481- double z = expval * 2.302585092994046 - exp2 * 0.6931471805599453 ;
482- double z2 = z * z ;
483- conv .U = (uint64_t )(exp2 + 1023 ) << 52 ;
484- // compute exp(z) using continued fractions
485- // https://en.wikipedia.org/wiki/Exponential_function#Continued_fractions_for_ex
486- conv .F *= 1 + 2 * z /(2 - z + (z2 /(6 + (z2 /(10 + z2 /14 )))));
492+ exp2 = (int )(expval * 3.321928094887362 + 0.5 );
493+ const double z = expval * 2.302585092994046 - exp2 * 0.6931471805599453 ;
494+ const double z2 = z * z ;
495+ conv .U = (uint64_t )(exp2 + 1023 ) << 52U ;
496+ // compute exp(z) using continued fractions, see https://en.wikipedia.org/wiki/Exponential_function#Continued_fractions_for_ex
497+ conv .F *= 1 + 2 * z / (2 - z + (z2 / (6 + (z2 / (10 + z2 / 14 )))));
487498 // correct for rounding errors
488499 if (value < conv .F ) {
489500 expval -- ;
490501 conv .F /= 10 ;
491502 }
492-
503+
493504 // the exponent format is "%+03d" and largest value is "307", so set aside 4-5 characters
494505 unsigned int minwidth = ((expval < 100 )&& (expval > -100 )) ? 4 : 5 ;
495-
506+
496507 // in "%g" mode, "prec" is the number of *significant figures* not decimals
497508 if (flags & FLAGS_ADAPT_EXP ) {
498509 // do we want to fall-back to "%f" mode?
499- if ((value >= 1e-4 )&& (value < 1e6 )) {
510+ if ((value >= 1e-4 ) && (value < 1e6 )) {
500511 if ((int )prec > expval ) {
501512 prec = (unsigned )((int )prec - expval - 1 );
502- } else {
513+ }
514+ else {
503515 prec = 0 ;
504516 }
505- flags |= FLAGS_PRECISION ; // make sure _ftoa respects precision
517+ flags |= FLAGS_PRECISION ; // make sure _ftoa respects precision
506518 // no characters in exponent
507519 minwidth = 0 ;
508520 expval = 0 ;
509- } else {
521+ }
522+ else {
510523 // we use one sigfig for the whole part
511- if ((prec > 0 )&& (flags & FLAGS_PRECISION )) -- prec ;
524+ if ((prec > 0 ) && (flags & FLAGS_PRECISION )) {
525+ -- prec ;
526+ }
512527 }
513528 }
529+
514530 // will everything fit?
515531 unsigned int fwidth = width ;
516532 if (width > minwidth ) {
@@ -526,7 +542,9 @@ static size_t _etoa(out_fct_type out, char* buffer, size_t idx, size_t maxlen, d
526542 }
527543
528544 // rescale the float value
529- if (expval ) value /= conv .F ;
545+ if (expval ) {
546+ value /= conv .F ;
547+ }
530548
531549 // output the floating part
532550 const size_t start_idx = idx ;
@@ -545,7 +563,6 @@ static size_t _etoa(out_fct_type out, char* buffer, size_t idx, size_t maxlen, d
545563 }
546564 return idx ;
547565}
548-
549566#endif // PRINTF_SUPPORT_EXPONENTIAL
550567#endif // PRINTF_SUPPORT_FLOAT
551568
0 commit comments