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.

pull/379/head
jarikomppa 2016-12-05 17:23:01 +02:00
parent 9a3f9dff13
commit 0e63382be0
1 changed files with 53 additions and 17 deletions

View File

@ -91,8 +91,11 @@ would print 12,345.
For integers and floats, you can use a "$" specifier and the number 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 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 tera and then printed, so "%$d" 1000 is "1.0 k", "%$.2d" 2536000 is
"2.42 m", etc. "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 In addition to octal and hexadecimal conversions, you can print
integers in binary: "%b" for 256 would print 100. 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 <stdarg.h> // for va_list() #include <stdarg.h> // 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 #ifndef STB_SPRINTF_MIN
#define STB_SPRINTF_MIN 512 // how many characters per callback #define STB_SPRINTF_MIN 512 // how many characters per callback
#endif #endif
@ -232,6 +232,9 @@ STBSP__PUBLICDEF int STB_SPRINTF_DECORATE( vsprintfcb )( STBSP_SPRINTFCB * callb
#define STBSP__NEGATIVE 128 #define STBSP__NEGATIVE 128
#define STBSP__METRIC_SUFFIX 256 #define STBSP__METRIC_SUFFIX 256
#define STBSP__HALFWIDTH 512 #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 // 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; } } #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; case '#': fl|=STBSP__LEADING_0X; ++f; continue;
// if we have thousand commas // if we have thousand commas
case '\'': fl|=STBSP__TRIPLET_COMMA; ++f; continue; case '\'': fl|=STBSP__TRIPLET_COMMA; ++f; continue;
// if we have kilo marker // if we have kilo marker (none->kilo->kibi->jedec)
case '$': fl|=STBSP__METRIC_SUFFIX; ++f; continue; 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 // if we have leading zero
case '0': fl|=STBSP__LEADINGZERO; ++f; goto flags_done; case '0': fl|=STBSP__LEADINGZERO; ++f; goto flags_done;
default: 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); fv = va_arg(va,double);
doafloat: doafloat:
// do kilos // 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) && (fv>-divisor)) break; fv/=divisor; fl+=0x1000000; }
}
if (pr==-1) pr=6; // default is 6 if (pr==-1) pr=6; // default is 6
// read the double into a string // read the double into a string
if ( stbsp__real_to_str( &sn, &l, num, &dp, fv, pr ) ) 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 // handle k,m,g,t
if (fl&STBSP__METRIC_SUFFIX) if (fl&STBSP__METRIC_SUFFIX)
{ {
tail[0]=1; char idx;
idx=1;
if (fl&STBSP__METRIC_NOSPACE)
idx=0;
tail[0]=idx;
tail[1]=' '; tail[1]=' ';
{ {
if (fl>>24) if (fl>>24)
{ { // SI kilo is 'k', JEDEC and SI kibits are 'K'.
tail[2]="_KMGT"[fl>>24]; if (fl&STBSP__METRIC_1024)
#ifdef STBSP__JEDEC_PREFIX tail[idx+1]="_KMGT"[fl>>24];
tail[0]=2; else
#else // SI prefix tail[idx+1]="_kMGT"[fl>>24];
tail[3]='i'; idx++;
tail[0]=3; // If printing kibits and not in jedec, add the 'i'.
#endif if (fl&STBSP__METRIC_1024&&!(fl&STBSP__METRIC_JEDEC))
{
tail[idx+1]='i';
idx++;
}
tail[0]=idx;
} }
} }
}; };