From a27e577c3eb38a2f40d4c55f37c8a58d6a750397 Mon Sep 17 00:00:00 2001 From: jarikomppa Date: Mon, 5 Dec 2016 14:56:35 +0200 Subject: [PATCH 1/3] The Si prefixes for mega, giga and tera are upper case (lower case m is not mega but milli) --- stb_sprintf.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stb_sprintf.h b/stb_sprintf.h index 23de7e4..0be456e 100644 --- a/stb_sprintf.h +++ b/stb_sprintf.h @@ -555,7 +555,7 @@ STBSP__PUBLICDEF int STB_SPRINTF_DECORATE( vsprintfcb )( STBSP_SPRINTFCB * callb pr = 0; // handle k,m,g,t - if (fl&STBSP__METRIC_SUFFIX) { tail[0]=1; tail[1]=' '; { if (fl>>24) { tail[2]="_kmgt"[fl>>24]; tail[0]=2; } } }; + if (fl&STBSP__METRIC_SUFFIX) { tail[0]=1; tail[1]=' '; { if (fl>>24) { tail[2]="_kMGT"[fl>>24]; tail[0]=2; } } }; flt_lead: // get the length that we copied From 9a3f9dff13cc07752cfa95b7fcce0a50004f9c30 Mon Sep 17 00:00:00 2001 From: jarikomppa Date: Mon, 5 Dec 2016 15:08:54 +0200 Subject: [PATCH 2/3] More proper fix for the prefixes (defaults to Ki style, with define for using K style instead) --- stb_sprintf.h | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/stb_sprintf.h b/stb_sprintf.h index 0be456e..c4d9573 100644 --- a/stb_sprintf.h +++ b/stb_sprintf.h @@ -133,6 +133,9 @@ PERFORMANCE vs MSVC 2008 32-/64-bit (GCC is even slower than MSVC): #include // for va_list() +// Uncomment for old-school prefixes (KB, MB instead of KiB, MiB) with the $ format +//#define STBSP__JEDEC_PREFIX + #ifndef STB_SPRINTF_MIN #define STB_SPRINTF_MIN 512 // how many characters per callback #endif @@ -555,7 +558,23 @@ STBSP__PUBLICDEF int STB_SPRINTF_DECORATE( vsprintfcb )( STBSP_SPRINTFCB * callb pr = 0; // handle k,m,g,t - if (fl&STBSP__METRIC_SUFFIX) { tail[0]=1; tail[1]=' '; { if (fl>>24) { tail[2]="_kMGT"[fl>>24]; tail[0]=2; } } }; + if (fl&STBSP__METRIC_SUFFIX) + { + tail[0]=1; + tail[1]=' '; + { + if (fl>>24) + { + tail[2]="_KMGT"[fl>>24]; +#ifdef STBSP__JEDEC_PREFIX + tail[0]=2; +#else // SI prefix + tail[3]='i'; + tail[0]=3; +#endif + } + } + }; flt_lead: // get the length that we copied From 0e63382be0f569f080698174a25d59f40a4d69f3 Mon Sep 17 00:00:00 2001 From: jarikomppa Date: Mon, 5 Dec 2016 17:23:01 +0200 Subject: [PATCH 3/3] A bit more involved change: support for both 1000 and 1024 divisors, and SI and JEDEC suffixes, as well as removing the space between number and suffix. --- stb_sprintf.h | 70 ++++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 53 insertions(+), 17 deletions(-) diff --git a/stb_sprintf.h b/stb_sprintf.h index c4d9573..3842a03 100644 --- a/stb_sprintf.h +++ b/stb_sprintf.h @@ -91,8 +91,11 @@ would print 12,345. For integers and floats, you can use a "$" specifier and the number will be converted to float and then divided to get kilo, mega, giga or -tera and then printed, so "%$d" 1024 is "1.0 k", "%$.2d" 2536000 is -"2.42 m", etc. +tera and then printed, so "%$d" 1000 is "1.0 k", "%$.2d" 2536000 is +"2.53 M", etc. For byte values, use two $:s, like "%$$d" to turn +2536000 to "2.42 Mi". If you prefer JEDEC suffixes to SI ones, use three +$:s: "%$$$d" -> "2.42 M". To remove the space between the number and the +suffix, add "_" specifier: "%_$d" -> "2.53M". In addition to octal and hexadecimal conversions, you can print integers in binary: "%b" for 256 would print 100. @@ -133,9 +136,6 @@ PERFORMANCE vs MSVC 2008 32-/64-bit (GCC is even slower than MSVC): #include // for va_list() -// Uncomment for old-school prefixes (KB, MB instead of KiB, MiB) with the $ format -//#define STBSP__JEDEC_PREFIX - #ifndef STB_SPRINTF_MIN #define STB_SPRINTF_MIN 512 // how many characters per callback #endif @@ -232,6 +232,9 @@ STBSP__PUBLICDEF int STB_SPRINTF_DECORATE( vsprintfcb )( STBSP_SPRINTFCB * callb #define STBSP__NEGATIVE 128 #define STBSP__METRIC_SUFFIX 256 #define STBSP__HALFWIDTH 512 + #define STBSP__METRIC_NOSPACE 1024 + #define STBSP__METRIC_1024 2048 + #define STBSP__METRIC_JEDEC 4096 // macros for the callback buffer stuff #define stbsp__chk_cb_bufL(bytes) { int len = (int)(bf-buf); if ((len+(bytes))>=STB_SPRINTF_MIN) { tlen+=len; if (0==(bf=buf=callback(buf,user,len))) goto done; } } @@ -279,8 +282,26 @@ STBSP__PUBLICDEF int STB_SPRINTF_DECORATE( vsprintfcb )( STBSP_SPRINTFCB * callb case '#': fl|=STBSP__LEADING_0X; ++f; continue; // if we have thousand commas case '\'': fl|=STBSP__TRIPLET_COMMA; ++f; continue; - // if we have kilo marker - case '$': fl|=STBSP__METRIC_SUFFIX; ++f; continue; + // if we have kilo marker (none->kilo->kibi->jedec) + case '$': + if (fl&STBSP__METRIC_SUFFIX) + { + if (fl&STBSP__METRIC_1024) + { + fl|=STBSP__METRIC_JEDEC; + } + else + { + fl|=STBSP__METRIC_1024; + } + } + else + { + fl|=STBSP__METRIC_SUFFIX; + } + ++f; continue; + // if we don't want space between metric suffix and number + case '_': fl|=STBSP__METRIC_NOSPACE; ++f; continue; // if we have leading zero case '0': fl|=STBSP__LEADINGZERO; ++f; goto flags_done; default: goto flags_done; @@ -505,7 +526,13 @@ STBSP__PUBLICDEF int STB_SPRINTF_DECORATE( vsprintfcb )( STBSP_SPRINTFCB * callb fv = va_arg(va,double); doafloat: // do kilos - if (fl&STBSP__METRIC_SUFFIX) {while(fl<0x4000000) { if ((fv<1024.0) && (fv>-1024.0)) break; fv/=1024.0; fl+=0x1000000; }} + if (fl&STBSP__METRIC_SUFFIX) + { + double divisor; + divisor=1000.0f; + if (fl&STBSP__METRIC_1024) divisor = 1024.0; + while(fl<0x4000000) { if ((fv-divisor)) break; fv/=divisor; fl+=0x1000000; } + } if (pr==-1) pr=6; // default is 6 // read the double into a string if ( stbsp__real_to_str( &sn, &l, num, &dp, fv, pr ) ) @@ -560,18 +587,27 @@ STBSP__PUBLICDEF int STB_SPRINTF_DECORATE( vsprintfcb )( STBSP_SPRINTFCB * callb // handle k,m,g,t if (fl&STBSP__METRIC_SUFFIX) { - tail[0]=1; + char idx; + idx=1; + if (fl&STBSP__METRIC_NOSPACE) + idx=0; + tail[0]=idx; tail[1]=' '; { if (fl>>24) - { - tail[2]="_KMGT"[fl>>24]; -#ifdef STBSP__JEDEC_PREFIX - tail[0]=2; -#else // SI prefix - tail[3]='i'; - tail[0]=3; -#endif + { // SI kilo is 'k', JEDEC and SI kibits are 'K'. + if (fl&STBSP__METRIC_1024) + tail[idx+1]="_KMGT"[fl>>24]; + else + tail[idx+1]="_kMGT"[fl>>24]; + idx++; + // If printing kibits and not in jedec, add the 'i'. + if (fl&STBSP__METRIC_1024&&!(fl&STBSP__METRIC_JEDEC)) + { + tail[idx+1]='i'; + idx++; + } + tail[0]=idx; } } };