26#ifndef STB_SPRINTF_H_INCLUDE
27#define STB_SPRINTF_H_INCLUDE
142#if defined(__has_feature)
143 #if __has_feature(address_sanitizer)
144 #define STBI__ASAN __attribute__((no_sanitize("address")))
151#ifdef STB_SPRINTF_STATIC
152#define STBSP__PUBLICDEC static
153#define STBSP__PUBLICDEF static STBI__ASAN
156#define STBSP__PUBLICDEC extern "C"
157#define STBSP__PUBLICDEF extern "C" STBI__ASAN
159#define STBSP__PUBLICDEC extern
160#define STBSP__PUBLICDEF STBI__ASAN
164#ifndef STB_SPRINTF_NOSTD
169#ifndef STB_SPRINTF_MIN
170#define STB_SPRINTF_MIN 512
172typedef char *STBSP_SPRINTFCB(
char *buf,
void *user,
int len);
174#ifndef STB_SPRINTF_DECORATE
175#define STB_SPRINTF_DECORATE(name) stbsp_##name
178STBSP__PUBLICDEF
int STB_SPRINTF_DECORATE(vsprintf)(
char *buf,
char const *fmt, va_list va);
179STBSP__PUBLICDEF
int STB_SPRINTF_DECORATE(vsnprintf)(
char *buf,
int count,
char const *fmt, va_list va);
180STBSP__PUBLICDEF
int STB_SPRINTF_DECORATE(sprintf)(
char *buf,
char const *fmt, ...);
181STBSP__PUBLICDEF
int STB_SPRINTF_DECORATE(snprintf)(
char *buf,
int count,
char const *fmt, ...);
183STBSP__PUBLICDEF
int STB_SPRINTF_DECORATE(vsprintfcb)(STBSP_SPRINTFCB *callback,
void *user,
char *buf,
char const *fmt, va_list va);
184STBSP__PUBLICDEF
void STB_SPRINTF_DECORATE(set_separators)(
char comma,
char period);
188#ifdef STB_SPRINTF_IMPLEMENTATION
190#ifndef STB_SPRINTF_NOSTD
194#define stbsp__uint32 unsigned int
195#define stbsp__int32 signed int
198#define stbsp__uint64 unsigned __int64
199#define stbsp__int64 signed __int64
201#define stbsp__uint64 unsigned long long
202#define stbsp__int64 signed long long
204#define stbsp__uint16 unsigned short
206#ifndef stbsp__uintptr
207#if defined(__ppc64__) || defined(__aarch64__) || defined(_M_X64) || defined(__x86_64__) || defined(__x86_64)
208#define stbsp__uintptr stbsp__uint64
210#define stbsp__uintptr stbsp__uint32
214#ifndef STB_SPRINTF_MSVC_MODE
215#if defined(_MSC_VER) && (_MSC_VER < 1900)
216#define STB_SPRINTF_MSVC_MODE
220#ifdef STB_SPRINTF_NOUNALIGNED
221#define STBSP__UNALIGNED(code)
223#define STBSP__UNALIGNED(code) code
226#ifndef STB_SPRINTF_NOFLOAT
228static stbsp__int32 stbsp__real_to_str(
char const **start, stbsp__uint32 *len,
char *out, stbsp__int32 *decimal_pos,
double value, stbsp__uint32 frac_digits);
229static stbsp__int32 stbsp__real_to_parts(stbsp__int64 *bits, stbsp__int32 *expo,
double value);
230#define STBSP__SPECIAL 0x7000
233static char stbsp__period =
'.';
234static char stbsp__comma =
',';
242 "00010203040506070809101112131415161718192021222324"
243 "25262728293031323334353637383940414243444546474849"
244 "50515253545556575859606162636465666768697071727374"
245 "75767778798081828384858687888990919293949596979899"
248STBSP__PUBLICDEF
void STB_SPRINTF_DECORATE(set_separators)(
char pcomma,
char pperiod)
250 stbsp__period = pperiod;
251 stbsp__comma = pcomma;
254#define STBSP__LEFTJUST 1
255#define STBSP__LEADINGPLUS 2
256#define STBSP__LEADINGSPACE 4
257#define STBSP__LEADING_0X 8
258#define STBSP__LEADINGZERO 16
259#define STBSP__INTMAX 32
260#define STBSP__TRIPLET_COMMA 64
261#define STBSP__NEGATIVE 128
262#define STBSP__METRIC_SUFFIX 256
263#define STBSP__HALFWIDTH 512
264#define STBSP__METRIC_NOSPACE 1024
265#define STBSP__METRIC_1024 2048
266#define STBSP__METRIC_JEDEC 4096
268static void stbsp__lead_sign(stbsp__uint32 fl,
char *sign)
271 if (fl & STBSP__NEGATIVE) {
274 }
else if (fl & STBSP__LEADINGSPACE) {
277 }
else if (fl & STBSP__LEADINGPLUS) {
283STBSP__PUBLICDEF
int STB_SPRINTF_DECORATE(vsprintfcb)(STBSP_SPRINTFCB *callback,
void *user,
char *buf,
char const *fmt, va_list va)
285 static char hex[] =
"0123456789abcdefxp";
286 static char hexu[] =
"0123456789ABCDEFXP";
294 stbsp__int32 fw, pr, tz;
298 #define stbsp__chk_cb_bufL(bytes) \
300 int len = (int)(bf - buf); \
301 if ((len + (bytes)) >= STB_SPRINTF_MIN) { \
303 if (0 == (bf = buf = callback(buf, user, len))) \
307 #define stbsp__chk_cb_buf(bytes) \
310 stbsp__chk_cb_bufL(bytes); \
313 #define stbsp__flush_cb() \
315 stbsp__chk_cb_bufL(STB_SPRINTF_MIN - 1); \
317 #define stbsp__cb_buf_clamp(cl, v) \
320 int lg = STB_SPRINTF_MIN - (int)(bf - buf); \
327 while (((stbsp__uintptr)f) & 3) {
334 stbsp__chk_cb_buf(1);
343 v = *(stbsp__uint32 *)f;
344 c = (~v) & 0x80808080;
345 if (((v ^ 0x25252525) - 0x01010101) & c)
347 if ((v - 0x01010101) & c)
350 if ((STB_SPRINTF_MIN - (
int)(bf - buf)) < 4)
352 #ifdef STB_SPRINTF_NOUNALIGNED
353 if(((stbsp__uintptr)bf) & 3) {
361 *(stbsp__uint32 *)bf = v;
382 fl |= STBSP__LEFTJUST;
387 fl |= STBSP__LEADINGPLUS;
392 fl |= STBSP__LEADINGSPACE;
397 fl |= STBSP__LEADING_0X;
402 fl |= STBSP__TRIPLET_COMMA;
407 if (fl & STBSP__METRIC_SUFFIX) {
408 if (fl & STBSP__METRIC_1024) {
409 fl |= STBSP__METRIC_JEDEC;
411 fl |= STBSP__METRIC_1024;
414 fl |= STBSP__METRIC_SUFFIX;
420 fl |= STBSP__METRIC_NOSPACE;
425 fl |= STBSP__LEADINGZERO;
428 default:
goto flags_done;
435 fw = va_arg(va, stbsp__uint32);
438 while ((f[0] >=
'0') && (f[0] <=
'9')) {
439 fw = fw * 10 + f[0] -
'0';
447 pr = va_arg(va, stbsp__uint32);
451 while ((f[0] >=
'0') && (f[0] <=
'9')) {
452 pr = pr * 10 + f[0] -
'0';
462 fl |= STBSP__HALFWIDTH;
467 fl |= ((
sizeof(long) == 8) ? STBSP__INTMAX : 0);
476 fl |= (
sizeof(size_t) == 8) ? STBSP__INTMAX : 0;
481 fl |= (
sizeof(ptrdiff_t) == 8) ? STBSP__INTMAX : 0;
485 fl |= (
sizeof(ptrdiff_t) == 8) ? STBSP__INTMAX : 0;
490 if ((f[1] ==
'6') && (f[2] ==
'4')) {
493 }
else if ((f[1] ==
'3') && (f[2] ==
'2')) {
496 fl |= ((
sizeof(
void *) == 8) ? STBSP__INTMAX : 0);
505 #define STBSP__NUMSZ 512
506 char num[STBSP__NUMSZ];
511 stbsp__uint32 l, n, cs;
513#ifndef STB_SPRINTF_NOFLOAT
521 s = va_arg(va,
char *);
527 if ((((stbsp__uintptr)sn) & 3) == 0)
536 n = (stbsp__uint32)(sn - s);
537 if (n >= (stbsp__uint32)pr)
539 n = ((stbsp__uint32)(pr - n)) >> 2;
542 stbsp__uint32 v = *(stbsp__uint32 *)sn;
543 if ((v - 0x01010101) & (~v) & 0x80808080UL)
551 l = (stbsp__uint32)(sn - s);
553 if (l > (stbsp__uint32)pr)
565 s = num + STBSP__NUMSZ - 1;
566 *s = (char)va_arg(va,
int);
577 int *d = va_arg(va,
int *);
578 *d = tlen + (int)(bf - buf);
581#ifdef STB_SPRINTF_NOFLOAT
590 s = (
char *)
"No float";
601 h = (f[0] ==
'A') ? hexu : hex;
602 fv = va_arg(va,
double);
606 if (stbsp__real_to_parts((stbsp__int64 *)&n64, &dp, fv))
607 fl |= STBSP__NEGATIVE;
611 stbsp__lead_sign(fl, lead);
614 dp = (n64) ? -1022 : 0;
616 n64 |= (((stbsp__uint64)1) << 52);
619 n64 += ((((stbsp__uint64)8) << 56) >> (pr * 4));
622#ifdef STB_SPRINTF_MSVC_MODE
626 lead[1 + lead[0]] =
'0';
627 lead[2 + lead[0]] =
'x';
630 *s++ = h[(n64 >> 60) & 15];
633 *s++ = stbsp__period;
640 if (pr > (stbsp__int32)n)
644 *s++ = h[(n64 >> 60) & 15];
655 n = (dp >= 1000) ? 6 : ((dp >= 100) ? 5 : ((dp >= 10) ? 4 : 3));
658 tail[n] =
'0' + dp % 10;
666 l = (int)(s - (num + 64));
673 h = (f[0] ==
'G') ? hexu : hex;
674 fv = va_arg(va,
double);
680 if (stbsp__real_to_str(&sn, &l, num, &dp, fv, (pr - 1) | 0x80000000))
681 fl |= STBSP__NEGATIVE;
685 if (l > (stbsp__uint32)pr)
687 while ((l > 1) && (pr) && (sn[l - 1] ==
'0')) {
693 if ((dp <= -4) || (dp > (stbsp__int32)n)) {
694 if (pr > (stbsp__int32)l)
702 pr = (dp < (stbsp__int32)l) ? l - dp : 0;
704 pr = -dp + ((pr > (stbsp__int32)l) ? (stbsp__int32) l : pr);
710 h = (f[0] ==
'E') ? hexu : hex;
711 fv = va_arg(va,
double);
715 if (stbsp__real_to_str(&sn, &l, num, &dp, fv, pr | 0x80000000))
716 fl |= STBSP__NEGATIVE;
719 stbsp__lead_sign(fl, lead);
720 if (dp == STBSP__SPECIAL) {
731 *s++ = stbsp__period;
734 if ((l - 1) > (stbsp__uint32)pr)
736 for (n = 1; n < l; n++)
749#ifdef STB_SPRINTF_MSVC_MODE
752 n = (dp >= 100) ? 5 : 4;
756 tail[n] =
'0' + dp % 10;
766 fv = va_arg(va,
double);
769 if (fl & STBSP__METRIC_SUFFIX) {
772 if (fl & STBSP__METRIC_1024)
774 while (fl < 0x4000000) {
775 if ((fv < divisor) && (fv > -divisor))
784 if (stbsp__real_to_str(&sn, &l, num, &dp, fv, pr))
785 fl |= STBSP__NEGATIVE;
788 stbsp__lead_sign(fl, lead);
789 if (dp == STBSP__SPECIAL) {
803 *s++ = stbsp__period;
805 if ((stbsp__int32)n > pr)
809 if ((((stbsp__uintptr)s) & 3) == 0)
815 *(stbsp__uint32 *)s = 0x30303030;
823 if ((stbsp__int32)(l + n) > pr)
833 cs = (fl & STBSP__TRIPLET_COMMA) ? ((600 - (stbsp__uint32)dp) % 3) : 0;
834 if ((stbsp__uint32)dp >= l) {
838 if ((fl & STBSP__TRIPLET_COMMA) && (++cs == 4)) {
848 if (n < (stbsp__uint32)dp) {
850 if ((fl & STBSP__TRIPLET_COMMA) == 0) {
852 if ((((stbsp__uintptr)s) & 3) == 0)
858 *(stbsp__uint32 *)s = 0x30303030;
864 if ((fl & STBSP__TRIPLET_COMMA) && (++cs == 4)) {
873 cs = (int)(s - (num + 64)) + (3 << 24);
875 *s++ = stbsp__period;
882 if ((fl & STBSP__TRIPLET_COMMA) && (++cs == 4)) {
888 if (n >= (stbsp__uint32)dp)
892 cs = (int)(s - (num + 64)) + (3 << 24);
894 *s++ = stbsp__period;
895 if ((l - dp) > (stbsp__uint32)pr)
907 if (fl & STBSP__METRIC_SUFFIX) {
910 if (fl & STBSP__METRIC_NOSPACE)
916 if (fl & STBSP__METRIC_1024)
917 tail[idx + 1] =
"_KMGT"[fl >> 24];
919 tail[idx + 1] =
"_kMGT"[fl >> 24];
922 if (fl & STBSP__METRIC_1024 && !(fl & STBSP__METRIC_JEDEC)) {
933 l = (stbsp__uint32)(s - (num + 64));
940 h = (f[0] ==
'B') ? hexu : hex;
942 if (fl & STBSP__LEADING_0X) {
947 l = (8 << 4) | (1 << 8);
953 if (fl & STBSP__LEADING_0X) {
957 l = (3 << 4) | (3 << 8);
961 fl |= (
sizeof(
void *) == 8) ? STBSP__INTMAX : 0;
962 pr =
sizeof(
void *) * 2;
963 fl &= ~STBSP__LEADINGZERO;
968 h = (f[0] ==
'X') ? hexu : hex;
969 l = (4 << 4) | (4 << 8);
971 if (fl & STBSP__LEADING_0X) {
978 if (fl & STBSP__INTMAX)
979 n64 = va_arg(va, stbsp__uint64);
981 n64 = va_arg(va, stbsp__uint32);
983 s = num + STBSP__NUMSZ;
991 cs = (((l >> 4) & 15)) << 24;
997 *--s = h[n64 & ((1 << (l >> 8)) - 1)];
999 if (!((n64) || ((stbsp__int32)((num + STBSP__NUMSZ) - s) < pr)))
1001 if (fl & STBSP__TRIPLET_COMMA) {
1003 if ((l & 15) == ((l >> 4) & 15)) {
1005 *--s = stbsp__comma;
1010 cs = (stbsp__uint32)((num + STBSP__NUMSZ) - s) + ((((l >> 4) & 15)) << 24);
1012 l = (stbsp__uint32)((num + STBSP__NUMSZ) - s);
1020 if (fl & STBSP__INTMAX) {
1021 stbsp__int64 i64 = va_arg(va, stbsp__int64);
1022 n64 = (stbsp__uint64)i64;
1023 if ((f[0] !=
'u') && (i64 < 0)) {
1024 n64 = (stbsp__uint64)-i64;
1025 fl |= STBSP__NEGATIVE;
1028 stbsp__int32 i = va_arg(va, stbsp__int32);
1029 n64 = (stbsp__uint32)i;
1030 if ((f[0] !=
'u') && (i < 0)) {
1031 n64 = (stbsp__uint32)-i;
1032 fl |= STBSP__NEGATIVE;
1036#ifndef STB_SPRINTF_NOFLOAT
1037 if (fl & STBSP__METRIC_SUFFIX) {
1042 fv = (double)(stbsp__int64)n64;
1048 s = num + STBSP__NUMSZ;
1054 if (n64 >= 100000000) {
1055 n = (stbsp__uint32)(n64 % 100000000);
1058 n = (stbsp__uint32)n64;
1061 if ((fl & STBSP__TRIPLET_COMMA) == 0) {
1064 *(stbsp__uint16 *)s = *(stbsp__uint16 *)&stbsp__digitpair.pair[(n % 100) * 2];
1069 if ((fl & STBSP__TRIPLET_COMMA) && (l++ == 3)) {
1071 *--s = stbsp__comma;
1074 *--s = (char)(n % 10) +
'0';
1079 if ((s[0] ==
'0') && (s != (num + STBSP__NUMSZ)))
1084 if ((fl & STBSP__TRIPLET_COMMA) && (l++ == 3)) {
1086 *--s = stbsp__comma;
1094 stbsp__lead_sign(fl, lead);
1097 l = (stbsp__uint32)((num + STBSP__NUMSZ) - s);
1108 if (pr < (stbsp__int32)l)
1110 n = pr + lead[0] + tail[0] + tz;
1111 if (fw < (stbsp__int32)n)
1117 if ((fl & STBSP__LEFTJUST) == 0) {
1118 if (fl & STBSP__LEADINGZERO)
1120 pr = (fw > pr) ? fw : pr;
1123 fl &= ~STBSP__TRIPLET_COMMA;
1133 if ((fl & STBSP__LEFTJUST) == 0)
1135 stbsp__cb_buf_clamp(i, fw);
1138 if ((((stbsp__uintptr)bf) & 3) == 0)
1144 *(stbsp__uint32 *)bf = 0x20202020;
1152 stbsp__chk_cb_buf(1);
1158 stbsp__cb_buf_clamp(i, lead[0]);
1164 stbsp__chk_cb_buf(1);
1170 cs = (fl & STBSP__TRIPLET_COMMA) ? ((stbsp__uint32)(c - ((pr + cs) % (c + 1)))) : 0;
1172 stbsp__cb_buf_clamp(i, pr);
1174 if ((fl & STBSP__TRIPLET_COMMA) == 0) {
1176 if ((((stbsp__uintptr)bf) & 3) == 0)
1182 *(stbsp__uint32 *)bf = 0x30303030;
1188 if ((fl & STBSP__TRIPLET_COMMA) && (cs++ == c)) {
1190 *bf++ = stbsp__comma;
1195 stbsp__chk_cb_buf(1);
1203 stbsp__cb_buf_clamp(i, lead[0]);
1209 stbsp__chk_cb_buf(1);
1216 stbsp__cb_buf_clamp(i, n);
1218 STBSP__UNALIGNED(
while (i >= 4) {
1219 *(stbsp__uint32 *)bf = *(stbsp__uint32 *)s;
1228 stbsp__chk_cb_buf(1);
1234 stbsp__cb_buf_clamp(i, tz);
1237 if ((((stbsp__uintptr)bf) & 3) == 0)
1243 *(stbsp__uint32 *)bf = 0x30303030;
1251 stbsp__chk_cb_buf(1);
1258 stbsp__cb_buf_clamp(i, tail[0]);
1264 stbsp__chk_cb_buf(1);
1268 if (fl & STBSP__LEFTJUST)
1272 stbsp__cb_buf_clamp(i, fw);
1275 if ((((stbsp__uintptr)bf) & 3) == 0)
1281 *(stbsp__uint32 *)bf = 0x20202020;
1287 stbsp__chk_cb_buf(1);
1293 s = num + STBSP__NUMSZ - 1;
1314 return tlen + (int)(bf - buf);
1318#undef STBSP__LEFTJUST
1319#undef STBSP__LEADINGPLUS
1320#undef STBSP__LEADINGSPACE
1321#undef STBSP__LEADING_0X
1322#undef STBSP__LEADINGZERO
1324#undef STBSP__TRIPLET_COMMA
1325#undef STBSP__NEGATIVE
1326#undef STBSP__METRIC_SUFFIX
1328#undef stbsp__chk_cb_bufL
1329#undef stbsp__chk_cb_buf
1330#undef stbsp__flush_cb
1331#undef stbsp__cb_buf_clamp
1336STBSP__PUBLICDEF
int STB_SPRINTF_DECORATE(sprintf)(
char *buf,
char const *fmt, ...)
1341 result = STB_SPRINTF_DECORATE(vsprintfcb)(0, 0, buf, fmt, va);
1346typedef struct stbsp__context {
1349 char tmp[STB_SPRINTF_MIN];
1352static char *stbsp__clamp_callback(
char *buf,
void *user,
int len)
1354 stbsp__context *c = (stbsp__context *)user;
1360 if (buf != c->buf) {
1375 return (c->count >= STB_SPRINTF_MIN) ? c->buf : c->tmp;
1378static char * stbsp__count_clamp_callback(
char * buf,
void * user,
int len )
1380 stbsp__context * c = (stbsp__context*)user;
1386STBSP__PUBLICDEF
int STB_SPRINTF_DECORATE( vsnprintf )(
char * buf,
int count,
char const * fmt, va_list va )
1391 if ( (count == 0) && !buf )
1395 STB_SPRINTF_DECORATE( vsprintfcb )( stbsp__count_clamp_callback, &c, c.tmp, fmt, va );
1406 STB_SPRINTF_DECORATE( vsprintfcb )( stbsp__clamp_callback, &c, stbsp__clamp_callback(0,&c,0), fmt, va );
1409 l = (int)( c.buf - buf );
1418STBSP__PUBLICDEF
int STB_SPRINTF_DECORATE(snprintf)(
char *buf,
int count,
char const *fmt, ...)
1424 result = STB_SPRINTF_DECORATE(vsnprintf)(buf, count, fmt, va);
1430STBSP__PUBLICDEF
int STB_SPRINTF_DECORATE(vsprintf)(
char *buf,
char const *fmt, va_list va)
1432 return STB_SPRINTF_DECORATE(vsprintfcb)(0, 0, buf, fmt, va);
1438#ifndef STB_SPRINTF_NOFLOAT
1441#define STBSP__COPYFP(dest, src) \
1444 for (cn = 0; cn < 8; cn++) \
1445 ((char *)&dest)[cn] = ((char *)&src)[cn]; \
1449static stbsp__int32 stbsp__real_to_parts(stbsp__int64 *bits, stbsp__int32 *expo,
double value)
1457 STBSP__COPYFP(b, d);
1459 *bits = b & ((((stbsp__uint64)1) << 52) - 1);
1460 *expo = (stbsp__int32)(((b >> 52) & 2047) - 1023);
1462 return (stbsp__int32)((stbsp__uint64) b >> 63);
1465static double const stbsp__bot[23] = {
1466 1e+000, 1e+001, 1e+002, 1e+003, 1e+004, 1e+005, 1e+006, 1e+007, 1e+008, 1e+009, 1e+010, 1e+011,
1467 1e+012, 1e+013, 1e+014, 1e+015, 1e+016, 1e+017, 1e+018, 1e+019, 1e+020, 1e+021, 1e+022
1469static double const stbsp__negbot[22] = {
1470 1e-001, 1e-002, 1e-003, 1e-004, 1e-005, 1e-006, 1e-007, 1e-008, 1e-009, 1e-010, 1e-011,
1471 1e-012, 1e-013, 1e-014, 1e-015, 1e-016, 1e-017, 1e-018, 1e-019, 1e-020, 1e-021, 1e-022
1473static double const stbsp__negboterr[22] = {
1474 -5.551115123125783e-018, -2.0816681711721684e-019, -2.0816681711721686e-020, -4.7921736023859299e-021, -8.1803053914031305e-022, 4.5251888174113741e-023,
1475 4.5251888174113739e-024, -2.0922560830128471e-025, -6.2281591457779853e-026, -3.6432197315497743e-027, 6.0503030718060191e-028, 2.0113352370744385e-029,
1476 -3.0373745563400371e-030, 1.1806906454401013e-032, -7.7705399876661076e-032, 2.0902213275965398e-033, -7.1542424054621921e-034, -7.1542424054621926e-035,
1477 2.4754073164739869e-036, 5.4846728545790429e-037, 9.2462547772103625e-038, -4.8596774326570872e-039
1479static double const stbsp__top[13] = {
1480 1e+023, 1e+046, 1e+069, 1e+092, 1e+115, 1e+138, 1e+161, 1e+184, 1e+207, 1e+230, 1e+253, 1e+276, 1e+299
1482static double const stbsp__negtop[13] = {
1483 1e-023, 1e-046, 1e-069, 1e-092, 1e-115, 1e-138, 1e-161, 1e-184, 1e-207, 1e-230, 1e-253, 1e-276, 1e-299
1485static double const stbsp__toperr[13] = {
1487 6.8601809640529717e+028,
1488 -7.253143638152921e+052,
1489 -4.3377296974619174e+075,
1490 -1.5559416129466825e+098,
1491 -3.2841562489204913e+121,
1492 -3.7745893248228135e+144,
1493 -1.7356668416969134e+167,
1494 -3.8893577551088374e+190,
1495 -9.9566444326005119e+213,
1496 6.3641293062232429e+236,
1497 -5.2069140800249813e+259,
1498 -5.2504760255204387e+282
1500static double const stbsp__negtoperr[13] = {
1501 3.9565301985100693e-040, -2.299904345391321e-063, 3.6506201437945798e-086, 1.1875228833981544e-109,
1502 -5.0644902316928607e-132, -6.7156837247865426e-155, -2.812077463003139e-178, -5.7778912386589953e-201,
1503 7.4997100559334532e-224, -4.6439668915134491e-247, -6.3691100762962136e-270, -9.436808465446358e-293,
1504 8.0970921678014997e-317
1507#if defined(_MSC_VER) && (_MSC_VER <= 1200)
1508static stbsp__uint64
const stbsp__powten[20] = {
1527 1000000000000000000,
1528 10000000000000000000U
1530#define stbsp__tento19th ((stbsp__uint64)1000000000000000000)
1532static stbsp__uint64
const stbsp__powten[20] = {
1548 1000000000000000ULL,
1549 10000000000000000ULL,
1550 100000000000000000ULL,
1551 1000000000000000000ULL,
1552 10000000000000000000ULL
1554#define stbsp__tento19th (1000000000000000000ULL)
1557#define stbsp__ddmulthi(oh, ol, xh, yh) \
1559 double ahi = 0, alo, bhi = 0, blo; \
1562 STBSP__COPYFP(bt, xh); \
1563 bt &= ((~(stbsp__uint64)0) << 27); \
1564 STBSP__COPYFP(ahi, bt); \
1566 STBSP__COPYFP(bt, yh); \
1567 bt &= ((~(stbsp__uint64)0) << 27); \
1568 STBSP__COPYFP(bhi, bt); \
1570 ol = ((ahi * bhi - oh) + ahi * blo + alo * bhi) + alo * blo; \
1573#define stbsp__ddtoS64(ob, xh, xl) \
1575 double ahi = 0, alo, vh, t; \
1576 ob = (stbsp__int64)ph; \
1580 alo = (xh - (ahi - t)) - (vh + t); \
1581 ob += (stbsp__int64)(ahi + alo + xl); \
1584#define stbsp__ddrenorm(oh, ol) \
1588 ol = ol - (s - oh); \
1592#define stbsp__ddmultlo(oh, ol, xh, xl, yh, yl) ol = ol + (xh * yl + xl * yh);
1594#define stbsp__ddmultlos(oh, ol, xh, yl) ol = ol + (xh * yl);
1596static void stbsp__raise_to_power10(
double *ohi,
double *olo,
double d, stbsp__int32 power)
1599 if ((power >= 0) && (power <= 22)) {
1600 stbsp__ddmulthi(ph, pl, d, stbsp__bot[power]);
1602 stbsp__int32 e, et, eb;
1608 et = (e * 0x2c9) >> 14;
1618 stbsp__ddmulthi(ph, pl, d, stbsp__negbot[eb]);
1619 stbsp__ddmultlos(ph, pl, d, stbsp__negboterr[eb]);
1622 stbsp__ddrenorm(ph, pl);
1624 stbsp__ddmulthi(p2h, p2l, ph, stbsp__negtop[et]);
1625 stbsp__ddmultlo(p2h, p2l, ph, pl, stbsp__negtop[et], stbsp__negtoperr[et]);
1635 stbsp__ddmulthi(ph, pl, d, stbsp__bot[eb]);
1637 stbsp__ddrenorm(ph, pl);
1638 stbsp__ddmulthi(p2h, p2l, ph, stbsp__bot[e]);
1639 stbsp__ddmultlos(p2h, p2l, stbsp__bot[e], pl);
1645 stbsp__ddrenorm(ph, pl);
1647 stbsp__ddmulthi(p2h, p2l, ph, stbsp__top[et]);
1648 stbsp__ddmultlo(p2h, p2l, ph, pl, stbsp__top[et], stbsp__toperr[et]);
1654 stbsp__ddrenorm(ph, pl);
1663static stbsp__int32 stbsp__real_to_str(
char const **start, stbsp__uint32 *len,
char *out, stbsp__int32 *decimal_pos,
double value, stbsp__uint32 frac_digits)
1666 stbsp__int64 bits = 0;
1667 stbsp__int32 expo, e, ng, tens;
1670 STBSP__COPYFP(bits, d);
1671 expo = (stbsp__int32)((bits >> 52) & 2047);
1672 ng = (stbsp__int32)((stbsp__uint64) bits >> 63);
1678 *start = (bits & ((((stbsp__uint64)1) << 52) - 1)) ?
"NaN" :
"Inf";
1679 *decimal_pos = STBSP__SPECIAL;
1686 if ((bits << 1) == 0)
1696 stbsp__int64 v = ((stbsp__uint64)1) << 51;
1697 while ((bits & v) == 0) {
1710 tens = (tens < 0) ? ((tens * 617) / 2048) : (((tens * 1233) / 4096) + 1);
1713 stbsp__raise_to_power10(&ph, &pl, d, 18 - tens);
1716 stbsp__ddtoS64(bits, ph, pl);
1719 if (((stbsp__uint64)bits) >= stbsp__tento19th)
1724 frac_digits = (frac_digits & 0x80000000) ? ((frac_digits & 0x7ffffff) + 1) : (tens + frac_digits);
1725 if ((frac_digits < 24)) {
1726 stbsp__uint32 dg = 1;
1727 if ((stbsp__uint64)bits >= stbsp__powten[9])
1729 while ((stbsp__uint64)bits >= stbsp__powten[dg]) {
1734 if (frac_digits < dg) {
1737 e = dg - frac_digits;
1738 if ((stbsp__uint32)e >= 24)
1740 r = stbsp__powten[e];
1741 bits = bits + (r / 2);
1742 if ((stbsp__uint64)bits >= stbsp__powten[dg])
1753 if (bits <= 0xffffffff)
1759 n = (stbsp__uint32)bits;
1760 while ((n % 1000) == 0)
1773 if (bits >= 100000000) {
1774 n = (stbsp__uint32)(bits % 100000000);
1777 n = (stbsp__uint32)bits;
1782 *(stbsp__uint16 *)out = *(stbsp__uint16 *)&stbsp__digitpair.pair[(n % 100) * 2];
1787 if ((e) && (out[0] ==
'0')) {
1799 *decimal_pos = tens;
1805#undef stbsp__ddmulthi
1806#undef stbsp__ddrenorm
1807#undef stbsp__ddmultlo
1808#undef stbsp__ddmultlos
1809#undef STBSP__SPECIAL
1820#undef STBSP__UNALIGNED