@ -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 <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
# 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 ) & & ( 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 ;
}
}
} ;