finished initial pass on stb_sprintf.h

This commit is contained in:
ed
2025-02-09 10:42:26 -05:00
parent 5798526a54
commit e4f797f594
+151 -92
View File
@@ -1285,7 +1285,8 @@ STBSP__PUBLICDEF int STB_SPRINTF_DECORATE(vsprintfcb)(STBSP_SPRINTFCB *callback,
dp = 0; dp = 0;
// clear tail, and clear leading if value is zero // clear tail, and clear leading if value is zero
tail[0] = 0; tail[0] = 0;
if (n64 == 0) { if (n64 == 0)
{
lead[0] = 0; lead[0] = 0;
if (pr == 0) { if (pr == 0) {
l = 0; l = 0;
@@ -1294,16 +1295,21 @@ STBSP__PUBLICDEF int STB_SPRINTF_DECORATE(vsprintfcb)(STBSP_SPRINTFCB *callback,
} }
} }
// convert to string // convert to string
for (;;) { for (;;)
*--s = h[n64 & ((1 << (l >> 8)) - 1)]; {
* -- s = h[n64 & ((1 << (l >> 8)) - 1)];
n64 >>= (l >> 8); n64 >>= (l >> 8);
if (!((n64) || ((stbsp__int32)((num + STBSP__NUMSZ) - s) < pr))) if (!((n64) || ((stbsp__int32)((num + STBSP__NUMSZ) - s) < pr)))
break; break;
if (fl & STBSP__TRIPLET_COMMA) { if (fl & STBSP__TRIPLET_COMMA) {
++l; ++l;
if ((l & 15) == ((l >> 4) & 15)) { if ((l & 15) == ((l >> 4) & 15)) {
l &= ~15; l &= ~15;
*--s = stbsp__comma; * -- s = stbsp__comma;
} }
} }
}; };
@@ -1367,39 +1373,46 @@ STBSP__PUBLICDEF int STB_SPRINTF_DECORATE(vsprintfcb)(STBSP_SPRINTFCB *callback,
if (n64 >= 100000000) { if (n64 >= 100000000) {
n = (stbsp__uint32)(n64 % 100000000); n = (stbsp__uint32)(n64 % 100000000);
n64 /= 100000000; n64 /= 100000000;
} else { }
else {
n = (stbsp__uint32)n64; n = (stbsp__uint32)n64;
n64 = 0; n64 = 0;
} }
if ((fl & STBSP__TRIPLET_COMMA) == 0) { if ((fl & STBSP__TRIPLET_COMMA) == 0)
{
do { do {
s -= 2; s -= 2;
*(stbsp__uint16 *)s = *(stbsp__uint16 *)&stbsp__digitpair.pair[(n % 100) * 2]; *(stbsp__uint16 *)s = *(stbsp__uint16 *)&stbsp__digitpair.pair[(n % 100) * 2];
n /= 100; n /= 100;
} while (n);
} }
while (n) { while (n);
}
while (n)
{
if ((fl & STBSP__TRIPLET_COMMA) && (l++ == 3)) { if ((fl & STBSP__TRIPLET_COMMA) && (l++ == 3)) {
l = 0; l = 0;
*--s = stbsp__comma; * -- s = stbsp__comma;
--o; -- o;
} else { }
*--s = (char)(n % 10) + '0'; else {
* -- s = (char)(n % 10) + '0';
n /= 10; n /= 10;
} }
} }
if (n64 == 0) { if (n64 == 0)
{
if ((s[0] == '0') && (s != (num + STBSP__NUMSZ))) if ((s[0] == '0') && (s != (num + STBSP__NUMSZ)))
++s; ++ s;
break; break;
} }
while (s != o) while (s != o) if ((fl & STBSP__TRIPLET_COMMA) && (l++ == 3))
if ((fl & STBSP__TRIPLET_COMMA) && (l++ == 3)) { {
l = 0; l = 0;
*--s = stbsp__comma; * -- s = stbsp__comma;
--o; -- o;
} else { }
*--s = '0'; else {
* -- s = '0';
} }
} }
@@ -1409,7 +1422,7 @@ STBSP__PUBLICDEF int STB_SPRINTF_DECORATE(vsprintfcb)(STBSP_SPRINTFCB *callback,
// get the length that we copied // get the length that we copied
l = (stbsp__uint32)((num + STBSP__NUMSZ) - s); l = (stbsp__uint32)((num + STBSP__NUMSZ) - s);
if (l == 0) { if (l == 0) {
*--s = '0'; * -- s = '0';
l = 1; l = 1;
} }
cs = l + (3 << 24); cs = l + (3 << 24);
@@ -1420,19 +1433,24 @@ STBSP__PUBLICDEF int STB_SPRINTF_DECORATE(vsprintfcb)(STBSP_SPRINTFCB *callback,
// get fw=leading/trailing space, pr=leading zeros // get fw=leading/trailing space, pr=leading zeros
if (pr < (stbsp__int32)l) if (pr < (stbsp__int32)l)
pr = l; pr = l;
n = pr + lead[0] + tail[0] + tz; n = pr + lead[0] + tail[0] + tz;
if (fw < (stbsp__int32)n) if (fw < (stbsp__int32)n)
fw = n; fw = n;
fw -= n; fw -= n;
pr -= l; pr -= l;
// handle right justify and leading zeros // handle right justify and leading zeros
if ((fl & STBSP__LEFTJUST) == 0) { if ((fl & STBSP__LEFTJUST) == 0)
if (fl & STBSP__LEADINGZERO) // if leading zeros, everything is in pr
{ {
if (fl & STBSP__LEADINGZERO) {
// if leading zeros, everything is in pr
pr = (fw > pr) ? fw : pr; pr = (fw > pr) ? fw : pr;
fw = 0; fw = 0;
} else { }
else {
fl &= ~STBSP__TRIPLET_COMMA; // if no leading zeros, then no commas fl &= ~STBSP__TRIPLET_COMMA; // if no leading zeros, then no commas
} }
} }
@@ -1444,15 +1462,15 @@ STBSP__PUBLICDEF int STB_SPRINTF_DECORATE(vsprintfcb)(STBSP_SPRINTFCB *callback,
stbsp__uint32 c; stbsp__uint32 c;
// copy leading spaces (or when doing %8.4d stuff) // copy leading spaces (or when doing %8.4d stuff)
if ((fl & STBSP__LEFTJUST) == 0) if ((fl & STBSP__LEFTJUST) == 0) while (fw > 0)
while (fw > 0) { {
stbsp__cb_buf_clamp(i, fw); stbsp__cb_buf_clamp(i, fw);
fw -= i; fw -= i;
while (i) { while (i) {
if ((((stbsp__uintptr)bf) & 3) == 0) if ((((stbsp__uintptr)bf) & 3) == 0)
break; break;
*bf++ = ' '; * bf ++ = ' ';
--i; -- i;
} }
while (i >= 4) { while (i >= 4) {
*(stbsp__uint32 *)bf = 0x20202020; *(stbsp__uint32 *)bf = 0x20202020;
@@ -1460,20 +1478,22 @@ STBSP__PUBLICDEF int STB_SPRINTF_DECORATE(vsprintfcb)(STBSP_SPRINTFCB *callback,
i -= 4; i -= 4;
} }
while (i) { while (i) {
*bf++ = ' '; * bf ++ = ' ';
--i; -- i;
} }
stbsp__chk_cb_buf(1); stbsp__chk_cb_buf(1);
} }
// copy leader // copy leader
sn = lead + 1; sn = lead + 1;
while (lead[0]) {
while (lead[0])
{
stbsp__cb_buf_clamp(i, lead[0]); stbsp__cb_buf_clamp(i, lead[0]);
lead[0] -= (char)i; lead[0] -= (char)i;
while (i) { while (i) {
*bf++ = *sn++; *bf ++ = *sn++;
--i; -- i;
} }
stbsp__chk_cb_buf(1); stbsp__chk_cb_buf(1);
} }
@@ -1482,15 +1502,19 @@ STBSP__PUBLICDEF int STB_SPRINTF_DECORATE(vsprintfcb)(STBSP_SPRINTFCB *callback,
c = cs >> 24; c = cs >> 24;
cs &= 0xffffff; cs &= 0xffffff;
cs = (fl & STBSP__TRIPLET_COMMA) ? ((stbsp__uint32)(c - ((pr + cs) % (c + 1)))) : 0; cs = (fl & STBSP__TRIPLET_COMMA) ? ((stbsp__uint32)(c - ((pr + cs) % (c + 1)))) : 0;
while (pr > 0) {
while (pr > 0)
{
stbsp__cb_buf_clamp(i, pr); stbsp__cb_buf_clamp(i, pr);
pr -= i; pr -= i;
if ((fl & STBSP__TRIPLET_COMMA) == 0) { if ((fl & STBSP__TRIPLET_COMMA) == 0)
while (i) { {
while (i)
{
if ((((stbsp__uintptr)bf) & 3) == 0) if ((((stbsp__uintptr)bf) & 3) == 0)
break; break;
*bf++ = '0'; *bf ++ = '0';
--i; -- i;
} }
while (i >= 4) { while (i >= 4) {
*(stbsp__uint32 *)bf = 0x30303030; *(stbsp__uint32 *)bf = 0x30303030;
@@ -1498,13 +1522,15 @@ STBSP__PUBLICDEF int STB_SPRINTF_DECORATE(vsprintfcb)(STBSP_SPRINTFCB *callback,
i -= 4; i -= 4;
} }
} }
while (i) { while (i)
{
if ((fl & STBSP__TRIPLET_COMMA) && (cs++ == c)) { if ((fl & STBSP__TRIPLET_COMMA) && (cs++ == c)) {
cs = 0; cs = 0;
*bf++ = stbsp__comma; *bf ++ = stbsp__comma;
} else }
*bf++ = '0'; else
--i; *bf ++ = '0';
-- i;
} }
stbsp__chk_cb_buf(1); stbsp__chk_cb_buf(1);
} }
@@ -1512,13 +1538,14 @@ STBSP__PUBLICDEF int STB_SPRINTF_DECORATE(vsprintfcb)(STBSP_SPRINTFCB *callback,
// copy leader if there is still one // copy leader if there is still one
sn = lead + 1; sn = lead + 1;
while (lead[0]) { while (lead[0])
{
stbsp__int32 i; stbsp__int32 i;
stbsp__cb_buf_clamp(i, lead[0]); stbsp__cb_buf_clamp(i, lead[0]);
lead[0] -= (char)i; lead[0] -= (char)i;
while (i) { while (i) {
*bf++ = *sn++; *bf ++ = *sn++;
--i; -- i;
} }
stbsp__chk_cb_buf(1); stbsp__chk_cb_buf(1);
} }
@@ -1578,8 +1605,8 @@ STBSP__PUBLICDEF int STB_SPRINTF_DECORATE(vsprintfcb)(STBSP_SPRINTFCB *callback,
stbsp__cb_buf_clamp(i, tail[0]); stbsp__cb_buf_clamp(i, tail[0]);
tail[0] -= (char)i; tail[0] -= (char)i;
while (i) { while (i) {
*bf++ = *sn++; *bf ++ = *sn ++;
--i; -- i;
} }
stbsp__chk_cb_buf(1); stbsp__chk_cb_buf(1);
} }
@@ -1676,7 +1703,7 @@ struct stbsp__context {
char tmp[STB_SPRINTF_MIN]; char tmp[STB_SPRINTF_MIN];
}; };
static char *stbsp__clamp_callback(const char *buf, void *user, int len) static char* stbsp__clamp_callback(const char* buf, void* user, int len)
{ {
stbsp__context *c = (stbsp__context *)user; stbsp__context *c = (stbsp__context *)user;
c->length += len; c->length += len;
@@ -1684,16 +1711,20 @@ static char *stbsp__clamp_callback(const char *buf, void *user, int len)
if (len > c->count) if (len > c->count)
len = c->count; len = c->count;
if (len) { if (len)
if (buf != c->buf) { {
const char *s, *se; if (buf != c->buf)
char *d; {
const char* s;
const char* se;
char* d;
d = c->buf; d = c->buf;
s = buf; s = buf;
se = buf + len; se = buf + len;
do { do {
*d++ = *s++; *d ++ = *s ++;
} while (s < se); }
while (s < se);
} }
c->buf += len; c->buf += len;
c->count -= len; c->count -= len;
@@ -1701,26 +1732,26 @@ static char *stbsp__clamp_callback(const char *buf, void *user, int len)
if (c->count <= 0) if (c->count <= 0)
return c->tmp; return c->tmp;
return (c->count >= STB_SPRINTF_MIN) ? c->buf : c->tmp; // go direct into buffer if you can return (c->count >= STB_SPRINTF_MIN) ? c->buf : c->tmp; // go direct into buffer if you can
} }
static char * stbsp__count_clamp_callback( const char * buf, void * user, int len ) static char* stbsp__count_clamp_callback(const char* buf, void* user, int len)
{ {
stbsp__context * c = (stbsp__context*)user; stbsp__context* c = (stbsp__context*)user;
(void) sizeof(buf); (void) sizeof(buf);
c->length += len; c->length += len;
return c->tmp; // go direct into buffer if you can return c->tmp; // go direct into buffer if you can
} }
STBSP__PUBLICDEF int STB_SPRINTF_DECORATE( vsnprintf )( char * buf, int count, char const * fmt, va_list va ) STBSP__PUBLICDEF int STB_SPRINTF_DECORATE( vsnprintf )( char* buf, int count, char const* fmt, va_list va )
{ {
stbsp__context c; stbsp__context c;
if ( (count == 0) && !buf ) if ( (count == 0) && !buf )
{ {
c.length = 0; c.length = 0;
STB_SPRINTF_DECORATE( vsprintfcb )( stbsp__count_clamp_callback, &c, c.tmp, fmt, va ); STB_SPRINTF_DECORATE( vsprintfcb )( stbsp__count_clamp_callback, &c, c.tmp, fmt, va );
} }
else else
@@ -1730,8 +1761,7 @@ STBSP__PUBLICDEF int STB_SPRINTF_DECORATE( vsnprintf )( char * buf, int count, c
c.buf = buf; c.buf = buf;
c.count = count; c.count = count;
c.length = 0; c.length = 0;
STB_SPRINTF_DECORATE( vsprintfcb )( stbsp__clamp_callback, &c, stbsp__clamp_callback(0, &c, 0), fmt, va );
STB_SPRINTF_DECORATE( vsprintfcb )( stbsp__clamp_callback, &c, stbsp__clamp_callback(0,&c,0), fmt, va );
// zero-terminate // zero-terminate
l = (int)( c.buf - buf ); l = (int)( c.buf - buf );
@@ -1739,11 +1769,10 @@ STBSP__PUBLICDEF int STB_SPRINTF_DECORATE( vsnprintf )( char * buf, int count, c
l = count - 1; l = count - 1;
buf[l] = 0; buf[l] = 0;
} }
return c.length; return c.length;
} }
STBSP__PUBLICDEF int STB_SPRINTF_DECORATE(snprintf)(char *buf, int count, char const *fmt, ...) { STBSP__PUBLICDEF int STB_SPRINTF_DECORATE(snprintf)(char* buf, int count, char const* fmt, ...) {
int result; int result;
va_list va; va_list va;
va_start(va, fmt); va_start(va, fmt);
@@ -1752,7 +1781,7 @@ STBSP__PUBLICDEF int STB_SPRINTF_DECORATE(snprintf)(char *buf, int count, char c
return result; return result;
} }
STBSP__PUBLICDEF int STB_SPRINTF_DECORATE(vsprintf)(char *buf, char const *fmt, va_list va) { return STB_SPRINTF_DECORATE(vsprintfcb)(0, 0, buf, fmt, va); } STBSP__PUBLICDEF int STB_SPRINTF_DECORATE(vsprintf)(char* buf, char const* fmt, va_list va) { return STB_SPRINTF_DECORATE(vsprintfcb)(0, 0, buf, fmt, va); }
// ======================================================================= // =======================================================================
// low level float utility functions // low level float utility functions
@@ -1907,44 +1936,54 @@ static stbsp__uint64 const stbsp__powten[20] = {
oh = s; \ oh = s; \
} }
#define stbsp__ddmultlo (oh, ol, xh, xl, yh, yl) ol = ol + (xh * yl + xl * yh); #define stbsp__ddmultlo(oh, ol, xh, xl, yh, yl) ol = ol + (xh * yl + xl * yh)
#define stbsp__ddmultlos(oh, ol, xh, yl) ol = ol + (xh * yl); #define stbsp__ddmultlos(oh, ol, xh, yl) ol = ol + (xh * yl)
static void stbsp__raise_to_power10(double *ohi, double *olo, double d, stbsp__int32 power) // power can be -323 to +350 static void stbsp__raise_to_power10(double* ohi, double* olo, double d, stbsp__int32 power) // power can be -323 to +350
{ {
double ph, pl; double ph, pl;
if ((power >= 0) && (power <= 22)) { if ((power >= 0) && (power <= 22)) {
stbsp__ddmulthi(ph, pl, d, stbsp__bot[power]); stbsp__ddmulthi(ph, pl, d, stbsp__bot[power]);
} else { }
else
{
stbsp__int32 e, et, eb; stbsp__int32 e, et, eb;
double p2h, p2l; double p2h, p2l;
e = power; e = power;
if (power < 0) if (power < 0)
e = -e; e = -e;
et = (e * 0x2c9) >> 14; /* %23 */ et = (e * 0x2c9) >> 14; /* %23 */
if (et > 13) if (et > 13)
et = 13; et = 13;
eb = e - (et * 23); eb = e - (et * 23);
ph = d; ph = d;
pl = 0.0; pl = 0.0;
if (power < 0) { if (power < 0)
{
if (eb) { if (eb) {
--eb; -- eb;
stbsp__ddmulthi(ph, pl, d, stbsp__negbot[eb]); stbsp__ddmulthi(ph, pl, d, stbsp__negbot[eb]);
stbsp__ddmultlos(ph, pl, d, stbsp__negboterr[eb]); stbsp__ddmultlos(ph, pl, d, stbsp__negboterr[eb]);
} }
if (et) { if (et) {
stbsp__ddrenorm(ph, pl); stbsp__ddrenorm(ph, pl);
--et; -- et;
stbsp__ddmulthi(p2h, p2l, ph, stbsp__negtop[et]); stbsp__ddmulthi(p2h, p2l, ph, stbsp__negtop[et]);
stbsp__ddmultlo(p2h, p2l, ph, pl, stbsp__negtop[et], stbsp__negtoperr[et]); stbsp__ddmultlo(p2h, p2l, ph, pl, stbsp__negtop[et], stbsp__negtoperr[et]);
ph = p2h; ph = p2h;
pl = p2l; pl = p2l;
} }
} else { }
if (eb) { else
{
if (eb)
{
e = eb; e = eb;
if (eb > 22) if (eb > 22)
eb = 22; eb = 22;
@@ -1958,9 +1997,10 @@ static void stbsp__raise_to_power10(double *ohi, double *olo, double d, stbsp__i
pl = p2l; pl = p2l;
} }
} }
if (et) { if (et)
{
stbsp__ddrenorm(ph, pl); stbsp__ddrenorm(ph, pl);
--et; -- et;
stbsp__ddmulthi(p2h, p2l, ph, stbsp__top[et]); stbsp__ddmulthi(p2h, p2l, ph, stbsp__top[et]);
stbsp__ddmultlo(p2h, p2l, ph, pl, stbsp__top[et], stbsp__toperr[et]); stbsp__ddmultlo(p2h, p2l, ph, pl, stbsp__top[et], stbsp__toperr[et]);
ph = p2h; ph = p2h;
@@ -1985,13 +2025,14 @@ static stbsp__int32 stbsp__real_to_str(char const **start, stbsp__uint32 *len, c
d = value; d = value;
STBSP__COPYFP(bits, d); STBSP__COPYFP(bits, d);
expo = (stbsp__int32)((bits >> 52) & 2047); expo = (stbsp__int32)((bits >> 52) & 2047);
ng = (stbsp__int32)((stbsp__uint64) bits >> 63); ng = (stbsp__int32)((stbsp__uint64) bits >> 63);
if (ng) if (ng)
d = -d; d = -d;
if (expo == 2047) // is nan or inf? if (expo == 2047) { // is nan or inf?
{
*start = (bits & ((((stbsp__uint64)1) << 52) - 1)) ? "NaN" : "Inf"; *start = (bits & ((((stbsp__uint64)1) << 52) - 1)) ? "NaN" : "Inf";
*decimal_pos = STBSP__SPECIAL; *decimal_pos = STBSP__SPECIAL;
*len = 3; *len = 3;
@@ -2012,7 +2053,7 @@ static stbsp__int32 stbsp__real_to_str(char const **start, stbsp__uint32 *len, c
{ {
stbsp__int64 v = ((stbsp__uint64)1) << 51; stbsp__int64 v = ((stbsp__uint64)1) << 51;
while ((bits & v) == 0) { while ((bits & v) == 0) {
--expo; -- expo;
v >>= 1; v >>= 1;
} }
} }
@@ -2034,37 +2075,47 @@ static stbsp__int32 stbsp__real_to_str(char const **start, stbsp__uint32 *len, c
// check if we undershot // check if we undershot
if (((stbsp__uint64)bits) >= stbsp__tento19th) if (((stbsp__uint64)bits) >= stbsp__tento19th)
++tens; ++ tens;
} }
// now do the rounding in integer land // now do the rounding in integer land
frac_digits = (frac_digits & 0x80000000) ? ((frac_digits & 0x7ffffff) + 1) : (tens + frac_digits); frac_digits = (frac_digits & 0x80000000) ? ((frac_digits & 0x7ffffff) + 1) : (tens + frac_digits);
if ((frac_digits < 24)) { if ((frac_digits < 24))
{
stbsp__uint32 dg = 1; stbsp__uint32 dg = 1;
if ((stbsp__uint64)bits >= stbsp__powten[9]) if ((stbsp__uint64)bits >= stbsp__powten[9])
dg = 10; dg = 10;
while ((stbsp__uint64)bits >= stbsp__powten[dg]) { while ((stbsp__uint64)bits >= stbsp__powten[dg]) {
++dg; ++ dg;
if (dg == 20) if (dg == 20)
goto noround; goto noround;
} }
if (frac_digits < dg) {
if (frac_digits < dg)
{
stbsp__uint64 r; stbsp__uint64 r;
// add 0.5 at the right position and round // add 0.5 at the right position and round
e = dg - frac_digits; e = dg - frac_digits;
if ((stbsp__uint32)e >= 24) if ((stbsp__uint32)e >= 24)
goto noround; goto noround;
r = stbsp__powten[e]; r = stbsp__powten[e];
bits = bits + (r / 2); bits = bits + (r / 2);
if ((stbsp__uint64)bits >= stbsp__powten[dg]) if ((stbsp__uint64)bits >= stbsp__powten[dg])
++tens; ++ tens;
bits /= r; bits /= r;
} }
noround:; noround:;
} }
// kill long trailing runs of zeros // kill long trailing runs of zeros
if (bits) { if (bits)
{
stbsp__uint32 n; stbsp__uint32 n;
for (;;) { for (;;) {
if (bits <= 0xffffffff) if (bits <= 0xffffffff)
@@ -2073,19 +2124,23 @@ static stbsp__int32 stbsp__real_to_str(char const **start, stbsp__uint32 *len, c
goto donez; goto donez;
bits /= 1000; bits /= 1000;
} }
n = (stbsp__uint32)bits; n = (stbsp__uint32)bits;
while ((n % 1000) == 0) while ((n % 1000) == 0)
n /= 1000; n /= 1000;
bits = n; bits = n;
donez:; donez:;
} }
// convert to string // convert to string
out += 64; out += 64;
e = 0; e = 0;
for (;;) { for (;;)
{
stbsp__uint32 n; stbsp__uint32 n;
char *o = out - 8; char* o = out - 8;
// do the conversion in chunks of U32s (avoid most 64-bit divides, worth it, constant denomiators be damned) // do the conversion in chunks of U32s (avoid most 64-bit divides, worth it, constant denomiators be damned)
if (bits >= 100000000) { if (bits >= 100000000) {
n = (stbsp__uint32)(bits % 100000000); n = (stbsp__uint32)(bits % 100000000);
@@ -2094,22 +2149,26 @@ static stbsp__int32 stbsp__real_to_str(char const **start, stbsp__uint32 *len, c
n = (stbsp__uint32)bits; n = (stbsp__uint32)bits;
bits = 0; bits = 0;
} }
while (n) { while (n) {
out -= 2; out -= 2;
*(stbsp__uint16 *)out = *(stbsp__uint16 *)&stbsp__digitpair.pair[(n % 100) * 2]; *(stbsp__uint16 *)out = *(stbsp__uint16 *)&stbsp__digitpair.pair[(n % 100) * 2];
n /= 100; n /= 100;
e += 2; e += 2;
} }
if (bits == 0) {
if (bits == 0)
{
if ((e) && (out[0] == '0')) { if ((e) && (out[0] == '0')) {
++out; ++ out;
--e; -- e;
} }
break; break;
} }
while (out != o) { while (out != o)
*--out = '0'; {
++e; * -- out = '0';
++ e;
} }
} }