29#ifndef STB_SPRINTF_H_INCLUDE
30#define STB_SPRINTF_H_INCLUDE
145#if defined(__clang__)
146 #if defined(__has_feature) && defined(__has_attribute)
147 #if __has_feature(address_sanitizer)
148 #if __has_attribute(__no_sanitize__)
149 #define STBSP__ASAN __attribute__((__no_sanitize__("address")))
150 #elif __has_attribute(__no_sanitize_address__)
151 #define STBSP__ASAN __attribute__((__no_sanitize_address__))
152 #elif __has_attribute(__no_address_safety_analysis__)
153 #define STBSP__ASAN __attribute__((__no_address_safety_analysis__))
157#elif defined(__GNUC__) && (__GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8))
158 #if defined(__SANITIZE_ADDRESS__) && __SANITIZE_ADDRESS__
159 #define STBSP__ASAN __attribute__((__no_sanitize_address__))
167#ifdef STB_SPRINTF_STATIC
168#define STBSP__PUBLICDEC static
169#define STBSP__PUBLICDEF static STBSP__ASAN
172#define STBSP__PUBLICDEC extern "C"
173#define STBSP__PUBLICDEF extern "C" STBSP__ASAN
175#define STBSP__PUBLICDEC extern
176#define STBSP__PUBLICDEF STBSP__ASAN
180#if defined(__has_attribute)
181 #if __has_attribute(format)
182 #define STBSP__ATTRIBUTE_FORMAT(fmt,va) __attribute__((format(printf,fmt,va)))
186#ifndef STBSP__ATTRIBUTE_FORMAT
187#define STBSP__ATTRIBUTE_FORMAT(fmt,va)
191#define STBSP__NOTUSED(v) (void)(v)
193#define STBSP__NOTUSED(v) (void)sizeof(v)
199#ifndef STB_SPRINTF_MIN
200#define STB_SPRINTF_MIN 512
204#ifndef STB_SPRINTF_DECORATE
205#define STB_SPRINTF_DECORATE(name) stbsp_##name
218#ifdef STB_SPRINTF_IMPLEMENTATION
220#define stbsp__uint32 unsigned int
221#define stbsp__int32 signed int
224#define stbsp__uint64 unsigned __int64
225#define stbsp__int64 signed __int64
227#define stbsp__uint64 unsigned long long
228#define stbsp__int64 signed long long
230#define stbsp__uint16 unsigned short
232#ifndef stbsp__uintptr
233#if defined(__ppc64__) || defined(__powerpc64__) || defined(__aarch64__) || defined(_M_X64) || defined(__x86_64__) || defined(__x86_64) || defined(__s390x__)
234#define stbsp__uintptr stbsp__uint64
236#define stbsp__uintptr stbsp__uint32
240#ifndef STB_SPRINTF_MSVC_MODE
241#if defined(_MSC_VER) && (_MSC_VER < 1900)
242#define STB_SPRINTF_MSVC_MODE
246#ifdef STB_SPRINTF_NOUNALIGNED
247#define STBSP__UNALIGNED(code)
249#define STBSP__UNALIGNED(code) code
252#ifndef STB_SPRINTF_NOFLOAT
254static stbsp__int32 stbsp__real_to_str(
char const **start, stbsp__uint32 *len,
char *out, stbsp__int32 *decimal_pos,
double value, stbsp__uint32 frac_digits);
255static stbsp__int32 stbsp__real_to_parts(stbsp__int64 *bits, stbsp__int32 *expo,
double value);
256#define STBSP__SPECIAL 0x7000
259static char stbsp__period =
'.';
260static char stbsp__comma =
',';
268 "00010203040506070809101112131415161718192021222324"
269 "25262728293031323334353637383940414243444546474849"
270 "50515253545556575859606162636465666768697071727374"
271 "75767778798081828384858687888990919293949596979899"
276 stbsp__period = pperiod;
277 stbsp__comma = pcomma;
280#define STBSP__LEFTJUST 1
281#define STBSP__LEADINGPLUS 2
282#define STBSP__LEADINGSPACE 4
283#define STBSP__LEADING_0X 8
284#define STBSP__LEADINGZERO 16
285#define STBSP__INTMAX 32
286#define STBSP__TRIPLET_COMMA 64
287#define STBSP__NEGATIVE 128
288#define STBSP__METRIC_SUFFIX 256
289#define STBSP__HALFWIDTH 512
290#define STBSP__METRIC_NOSPACE 1024
291#define STBSP__METRIC_1024 2048
292#define STBSP__METRIC_JEDEC 4096
294static void stbsp__lead_sign(stbsp__uint32 fl,
char *sign)
297 if (fl & STBSP__NEGATIVE) {
300 }
else if (fl & STBSP__LEADINGSPACE) {
303 }
else if (fl & STBSP__LEADINGPLUS) {
309static STBSP__ASAN stbsp__uint32 stbsp__strlen_limited(
char const *s, stbsp__uint32 limit)
315 if (((stbsp__uintptr)sn & 3) == 0)
318 if (!limit || *sn == 0)
319 return (stbsp__uint32)(sn - s);
331 stbsp__uint32 v = *(stbsp__uint32 *)sn;
333 if ((v - 0x01010101) & (~v) & 0x80808080UL)
341 while (limit && *sn) {
346 return (stbsp__uint32)(sn - s);
351 static char hex[] =
"0123456789abcdefxp";
352 static char hexu[] =
"0123456789ABCDEFXP";
360 stbsp__int32 fw, pr, tz;
364 #define stbsp__chk_cb_bufL(bytes) \
366 int len = (int)(bf - buf); \
367 if ((len + (bytes)) >= STB_SPRINTF_MIN) { \
369 if (0 == (bf = buf = callback(buf, user, len))) \
373 #define stbsp__chk_cb_buf(bytes) \
376 stbsp__chk_cb_bufL(bytes); \
379 #define stbsp__flush_cb() \
381 stbsp__chk_cb_bufL(STB_SPRINTF_MIN - 1); \
383 #define stbsp__cb_buf_clamp(cl, v) \
386 int lg = STB_SPRINTF_MIN - (int)(bf - buf); \
393 while (((stbsp__uintptr)f) & 3) {
400 stbsp__chk_cb_buf(1);
409 v = *(stbsp__uint32 *)f;
410 c = (~v) & 0x80808080;
411 if (((v ^ 0x25252525) - 0x01010101) & c)
413 if ((v - 0x01010101) & c)
418 #ifdef STB_SPRINTF_NOUNALIGNED
419 if(((stbsp__uintptr)bf) & 3) {
427 *(stbsp__uint32 *)bf = v;
448 fl |= STBSP__LEFTJUST;
453 fl |= STBSP__LEADINGPLUS;
458 fl |= STBSP__LEADINGSPACE;
463 fl |= STBSP__LEADING_0X;
468 fl |= STBSP__TRIPLET_COMMA;
473 if (fl & STBSP__METRIC_SUFFIX) {
474 if (fl & STBSP__METRIC_1024) {
475 fl |= STBSP__METRIC_JEDEC;
477 fl |= STBSP__METRIC_1024;
480 fl |= STBSP__METRIC_SUFFIX;
486 fl |= STBSP__METRIC_NOSPACE;
491 fl |= STBSP__LEADINGZERO;
494 default:
goto flags_done;
501 fw = va_arg(va, stbsp__uint32);
504 while ((f[0] >=
'0') && (f[0] <=
'9')) {
505 fw = fw * 10 + f[0] -
'0';
513 pr = va_arg(va, stbsp__uint32);
517 while ((f[0] >=
'0') && (f[0] <=
'9')) {
518 pr = pr * 10 + f[0] -
'0';
528 fl |= STBSP__HALFWIDTH;
535 fl |= ((
sizeof(long) == 8) ? STBSP__INTMAX : 0);
544 fl |= (
sizeof(size_t) == 8) ? STBSP__INTMAX : 0;
549 fl |= (
sizeof(ptrdiff_t) == 8) ? STBSP__INTMAX : 0;
553 fl |= (
sizeof(ptrdiff_t) == 8) ? STBSP__INTMAX : 0;
558 if ((f[1] ==
'6') && (f[2] ==
'4')) {
561 }
else if ((f[1] ==
'3') && (f[2] ==
'2')) {
564 fl |= ((
sizeof(
void *) == 8) ? STBSP__INTMAX : 0);
573 #define STBSP__NUMSZ 512
574 char num[STBSP__NUMSZ];
579 stbsp__uint32 l, n, cs;
581#ifndef STB_SPRINTF_NOFLOAT
589 s = va_arg(va,
char *);
594 l = stbsp__strlen_limited(s, (pr >= 0) ? pr : ~0u);
605 s = num + STBSP__NUMSZ - 1;
606 *s = (char)va_arg(va,
int);
617 int *d = va_arg(va,
int *);
618 *d = tlen + (int)(bf - buf);
621#ifdef STB_SPRINTF_NOFLOAT
630 s = (
char *)
"No float";
641 h = (f[0] ==
'A') ? hexu : hex;
642 fv = va_arg(va,
double);
646 if (stbsp__real_to_parts((stbsp__int64 *)&n64, &dp, fv))
647 fl |= STBSP__NEGATIVE;
651 stbsp__lead_sign(fl, lead);
654 dp = (n64) ? -1022 : 0;
656 n64 |= (((stbsp__uint64)1) << 52);
659 n64 += ((((stbsp__uint64)8) << 56) >> (pr * 4));
662#ifdef STB_SPRINTF_MSVC_MODE
666 lead[1 + lead[0]] =
'0';
667 lead[2 + lead[0]] =
'x';
670 *s++ = h[(n64 >> 60) & 15];
673 *s++ = stbsp__period;
680 if (pr > (stbsp__int32)n)
684 *s++ = h[(n64 >> 60) & 15];
695 n = (dp >= 1000) ? 6 : ((dp >= 100) ? 5 : ((dp >= 10) ? 4 : 3));
698 tail[n] =
'0' + dp % 10;
706 l = (int)(s - (num + 64));
713 h = (f[0] ==
'G') ? hexu : hex;
714 fv = va_arg(va,
double);
720 if (stbsp__real_to_str(&sn, &l, num, &dp, fv, (pr - 1) | 0x80000000))
721 fl |= STBSP__NEGATIVE;
725 if (l > (stbsp__uint32)pr)
727 while ((l > 1) && (pr) && (sn[l - 1] ==
'0')) {
733 if ((dp <= -4) || (dp > (stbsp__int32)n)) {
734 if (pr > (stbsp__int32)l)
742 pr = (dp < (stbsp__int32)l) ? l - dp : 0;
744 pr = -dp + ((pr > (stbsp__int32)l) ? (stbsp__int32) l : pr);
750 h = (f[0] ==
'E') ? hexu : hex;
751 fv = va_arg(va,
double);
755 if (stbsp__real_to_str(&sn, &l, num, &dp, fv, pr | 0x80000000))
756 fl |= STBSP__NEGATIVE;
759 stbsp__lead_sign(fl, lead);
760 if (dp == STBSP__SPECIAL) {
771 *s++ = stbsp__period;
774 if ((l - 1) > (stbsp__uint32)pr)
776 for (n = 1; n < l; n++)
789#ifdef STB_SPRINTF_MSVC_MODE
792 n = (dp >= 100) ? 5 : 4;
796 tail[n] =
'0' + dp % 10;
806 fv = va_arg(va,
double);
809 if (fl & STBSP__METRIC_SUFFIX) {
812 if (fl & STBSP__METRIC_1024)
814 while (fl < 0x4000000) {
815 if ((fv < divisor) && (fv > -divisor))
824 if (stbsp__real_to_str(&sn, &l, num, &dp, fv, pr))
825 fl |= STBSP__NEGATIVE;
828 stbsp__lead_sign(fl, lead);
829 if (dp == STBSP__SPECIAL) {
843 *s++ = stbsp__period;
845 if ((stbsp__int32)n > pr)
849 if ((((stbsp__uintptr)s) & 3) == 0)
855 *(stbsp__uint32 *)s = 0x30303030;
863 if ((stbsp__int32)(l + n) > pr)
873 cs = (fl & STBSP__TRIPLET_COMMA) ? ((600 - (stbsp__uint32)dp) % 3) : 0;
874 if ((stbsp__uint32)dp >= l) {
878 if ((fl & STBSP__TRIPLET_COMMA) && (++cs == 4)) {
888 if (n < (stbsp__uint32)dp) {
890 if ((fl & STBSP__TRIPLET_COMMA) == 0) {
892 if ((((stbsp__uintptr)s) & 3) == 0)
898 *(stbsp__uint32 *)s = 0x30303030;
904 if ((fl & STBSP__TRIPLET_COMMA) && (++cs == 4)) {
913 cs = (int)(s - (num + 64)) + (3 << 24);
915 *s++ = stbsp__period;
922 if ((fl & STBSP__TRIPLET_COMMA) && (++cs == 4)) {
928 if (n >= (stbsp__uint32)dp)
932 cs = (int)(s - (num + 64)) + (3 << 24);
934 *s++ = stbsp__period;
935 if ((l - dp) > (stbsp__uint32)pr)
947 if (fl & STBSP__METRIC_SUFFIX) {
950 if (fl & STBSP__METRIC_NOSPACE)
956 if (fl & STBSP__METRIC_1024)
957 tail[idx + 1] =
"_KMGT"[fl >> 24];
959 tail[idx + 1] =
"_kMGT"[fl >> 24];
962 if (fl & STBSP__METRIC_1024 && !(fl & STBSP__METRIC_JEDEC)) {
973 l = (stbsp__uint32)(s - (num + 64));
980 h = (f[0] ==
'B') ? hexu : hex;
982 if (fl & STBSP__LEADING_0X) {
987 l = (8 << 4) | (1 << 8);
993 if (fl & STBSP__LEADING_0X) {
997 l = (3 << 4) | (3 << 8);
1001 fl |= (
sizeof(
void *) == 8) ? STBSP__INTMAX : 0;
1002 pr =
sizeof(
void *) * 2;
1003 fl &= ~STBSP__LEADINGZERO;
1008 h = (f[0] ==
'X') ? hexu : hex;
1009 l = (4 << 4) | (4 << 8);
1011 if (fl & STBSP__LEADING_0X) {
1018 if (fl & STBSP__INTMAX)
1019 n64 = va_arg(va, stbsp__uint64);
1021 n64 = va_arg(va, stbsp__uint32);
1023 s = num + STBSP__NUMSZ;
1037 *--s = h[n64 & ((1 << (l >> 8)) - 1)];
1039 if (!((n64) || ((stbsp__int32)((num + STBSP__NUMSZ) - s) < pr)))
1041 if (fl & STBSP__TRIPLET_COMMA) {
1043 if ((l & 15) == ((l >> 4) & 15)) {
1045 *--s = stbsp__comma;
1050 cs = (stbsp__uint32)((num + STBSP__NUMSZ) - s) + ((((l >> 4) & 15)) << 24);
1052 l = (stbsp__uint32)((num + STBSP__NUMSZ) - s);
1060 if (fl & STBSP__INTMAX) {
1061 stbsp__int64 i64 = va_arg(va, stbsp__int64);
1062 n64 = (stbsp__uint64)i64;
1063 if ((f[0] !=
'u') && (i64 < 0)) {
1064 n64 = (stbsp__uint64)-i64;
1065 fl |= STBSP__NEGATIVE;
1068 stbsp__int32 i = va_arg(va, stbsp__int32);
1069 n64 = (stbsp__uint32)i;
1070 if ((f[0] !=
'u') && (i < 0)) {
1071 n64 = (stbsp__uint32)-i;
1072 fl |= STBSP__NEGATIVE;
1076#ifndef STB_SPRINTF_NOFLOAT
1077 if (fl & STBSP__METRIC_SUFFIX) {
1082 fv = (double)(stbsp__int64)n64;
1088 s = num + STBSP__NUMSZ;
1094 if (n64 >= 100000000) {
1095 n = (stbsp__uint32)(n64 % 100000000);
1098 n = (stbsp__uint32)n64;
1101 if ((fl & STBSP__TRIPLET_COMMA) == 0) {
1104 *(stbsp__uint16 *)s = *(stbsp__uint16 *)&stbsp__digitpair.pair[(n % 100) * 2];
1109 if ((fl & STBSP__TRIPLET_COMMA) && (l++ == 3)) {
1111 *--s = stbsp__comma;
1114 *--s = (char)(n % 10) +
'0';
1119 if ((s[0] ==
'0') && (s != (num + STBSP__NUMSZ)))
1124 if ((fl & STBSP__TRIPLET_COMMA) && (l++ == 3)) {
1126 *--s = stbsp__comma;
1134 stbsp__lead_sign(fl, lead);
1137 l = (stbsp__uint32)((num + STBSP__NUMSZ) - s);
1148 if (pr < (stbsp__int32)l)
1150 n = pr + lead[0] + tail[0] + tz;
1151 if (fw < (stbsp__int32)n)
1157 if ((fl & STBSP__LEFTJUST) == 0) {
1158 if (fl & STBSP__LEADINGZERO)
1160 pr = (fw > pr) ? fw : pr;
1163 fl &= ~STBSP__TRIPLET_COMMA;
1173 if ((fl & STBSP__LEFTJUST) == 0)
1175 stbsp__cb_buf_clamp(i, fw);
1178 if ((((stbsp__uintptr)bf) & 3) == 0)
1184 *(stbsp__uint32 *)bf = 0x20202020;
1192 stbsp__chk_cb_buf(1);
1198 stbsp__cb_buf_clamp(i, lead[0]);
1204 stbsp__chk_cb_buf(1);
1210 cs = (fl & STBSP__TRIPLET_COMMA) ? ((stbsp__uint32)(c - ((pr + cs) % (c + 1)))) : 0;
1212 stbsp__cb_buf_clamp(i, pr);
1214 if ((fl & STBSP__TRIPLET_COMMA) == 0) {
1216 if ((((stbsp__uintptr)bf) & 3) == 0)
1222 *(stbsp__uint32 *)bf = 0x30303030;
1228 if ((fl & STBSP__TRIPLET_COMMA) && (cs++ == c)) {
1230 *bf++ = stbsp__comma;
1235 stbsp__chk_cb_buf(1);
1243 stbsp__cb_buf_clamp(i, lead[0]);
1249 stbsp__chk_cb_buf(1);
1256 stbsp__cb_buf_clamp(i, n);
1258 STBSP__UNALIGNED(
while (i >= 4) {
1259 *(stbsp__uint32
volatile *)bf = *(stbsp__uint32
volatile *)s;
1268 stbsp__chk_cb_buf(1);
1274 stbsp__cb_buf_clamp(i, tz);
1277 if ((((stbsp__uintptr)bf) & 3) == 0)
1283 *(stbsp__uint32 *)bf = 0x30303030;
1291 stbsp__chk_cb_buf(1);
1298 stbsp__cb_buf_clamp(i, tail[0]);
1304 stbsp__chk_cb_buf(1);
1308 if (fl & STBSP__LEFTJUST)
1312 stbsp__cb_buf_clamp(i, fw);
1315 if ((((stbsp__uintptr)bf) & 3) == 0)
1321 *(stbsp__uint32 *)bf = 0x20202020;
1327 stbsp__chk_cb_buf(1);
1333 s = num + STBSP__NUMSZ - 1;
1354 return tlen + (int)(bf - buf);
1358#undef STBSP__LEFTJUST
1359#undef STBSP__LEADINGPLUS
1360#undef STBSP__LEADINGSPACE
1361#undef STBSP__LEADING_0X
1362#undef STBSP__LEADINGZERO
1364#undef STBSP__TRIPLET_COMMA
1365#undef STBSP__NEGATIVE
1366#undef STBSP__METRIC_SUFFIX
1368#undef stbsp__chk_cb_bufL
1369#undef stbsp__chk_cb_buf
1370#undef stbsp__flush_cb
1371#undef stbsp__cb_buf_clamp
1386typedef struct stbsp__context {
1393static char *stbsp__clamp_callback(
const char *buf,
void *user,
int len)
1395 stbsp__context *c = (stbsp__context *)user;
1402 if (buf != c->buf) {
1421static char * stbsp__count_clamp_callback(
const char * buf,
void * user,
int len )
1423 stbsp__context * c = (stbsp__context*)user;
1434 if ( (count == 0) && !buf )
1451 l = (int)( c.buf - buf );
1480#ifndef STB_SPRINTF_NOFLOAT
1483#define STBSP__COPYFP(dest, src) \
1486 for (cn = 0; cn < 8; cn++) \
1487 ((char *)&dest)[cn] = ((char *)&src)[cn]; \
1491static stbsp__int32 stbsp__real_to_parts(stbsp__int64 *bits, stbsp__int32 *expo,
double value)
1499 STBSP__COPYFP(b, d);
1501 *bits = b & ((((stbsp__uint64)1) << 52) - 1);
1502 *expo = (stbsp__int32)(((b >> 52) & 2047) - 1023);
1504 return (stbsp__int32)((stbsp__uint64) b >> 63);
1507static double const stbsp__bot[23] = {
1508 1e+000, 1e+001, 1e+002, 1e+003, 1e+004, 1e+005, 1e+006, 1e+007, 1e+008, 1e+009, 1e+010, 1e+011,
1509 1e+012, 1e+013, 1e+014, 1e+015, 1e+016, 1e+017, 1e+018, 1e+019, 1e+020, 1e+021, 1e+022
1511static double const stbsp__negbot[22] = {
1512 1e-001, 1e-002, 1e-003, 1e-004, 1e-005, 1e-006, 1e-007, 1e-008, 1e-009, 1e-010, 1e-011,
1513 1e-012, 1e-013, 1e-014, 1e-015, 1e-016, 1e-017, 1e-018, 1e-019, 1e-020, 1e-021, 1e-022
1515static double const stbsp__negboterr[22] = {
1516 -5.551115123125783e-018, -2.0816681711721684e-019, -2.0816681711721686e-020, -4.7921736023859299e-021, -8.1803053914031305e-022, 4.5251888174113741e-023,
1517 4.5251888174113739e-024, -2.0922560830128471e-025, -6.2281591457779853e-026, -3.6432197315497743e-027, 6.0503030718060191e-028, 2.0113352370744385e-029,
1518 -3.0373745563400371e-030, 1.1806906454401013e-032, -7.7705399876661076e-032, 2.0902213275965398e-033, -7.1542424054621921e-034, -7.1542424054621926e-035,
1519 2.4754073164739869e-036, 5.4846728545790429e-037, 9.2462547772103625e-038, -4.8596774326570872e-039
1521static double const stbsp__top[13] = {
1522 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
1524static double const stbsp__negtop[13] = {
1525 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
1527static double const stbsp__toperr[13] = {
1529 6.8601809640529717e+028,
1530 -7.253143638152921e+052,
1531 -4.3377296974619174e+075,
1532 -1.5559416129466825e+098,
1533 -3.2841562489204913e+121,
1534 -3.7745893248228135e+144,
1535 -1.7356668416969134e+167,
1536 -3.8893577551088374e+190,
1537 -9.9566444326005119e+213,
1538 6.3641293062232429e+236,
1539 -5.2069140800249813e+259,
1540 -5.2504760255204387e+282
1542static double const stbsp__negtoperr[13] = {
1543 3.9565301985100693e-040, -2.299904345391321e-063, 3.6506201437945798e-086, 1.1875228833981544e-109,
1544 -5.0644902316928607e-132, -6.7156837247865426e-155, -2.812077463003139e-178, -5.7778912386589953e-201,
1545 7.4997100559334532e-224, -4.6439668915134491e-247, -6.3691100762962136e-270, -9.436808465446358e-293,
1546 8.0970921678014997e-317
1549#if defined(_MSC_VER) && (_MSC_VER <= 1200)
1550static stbsp__uint64
const stbsp__powten[20] = {
1569 1000000000000000000,
1570 10000000000000000000U
1572#define stbsp__tento19th ((stbsp__uint64)1000000000000000000)
1574static stbsp__uint64
const stbsp__powten[20] = {
1590 1000000000000000ULL,
1591 10000000000000000ULL,
1592 100000000000000000ULL,
1593 1000000000000000000ULL,
1594 10000000000000000000ULL
1596#define stbsp__tento19th (1000000000000000000ULL)
1599#define stbsp__ddmulthi(oh, ol, xh, yh) \
1601 double ahi = 0, alo, bhi = 0, blo; \
1604 STBSP__COPYFP(bt, xh); \
1605 bt &= ((~(stbsp__uint64)0) << 27); \
1606 STBSP__COPYFP(ahi, bt); \
1608 STBSP__COPYFP(bt, yh); \
1609 bt &= ((~(stbsp__uint64)0) << 27); \
1610 STBSP__COPYFP(bhi, bt); \
1612 ol = ((ahi * bhi - oh) + ahi * blo + alo * bhi) + alo * blo; \
1615#define stbsp__ddtoS64(ob, xh, xl) \
1617 double ahi = 0, alo, vh, t; \
1618 ob = (stbsp__int64)xh; \
1622 alo = (xh - (ahi - t)) - (vh + t); \
1623 ob += (stbsp__int64)(ahi + alo + xl); \
1626#define stbsp__ddrenorm(oh, ol) \
1630 ol = ol - (s - oh); \
1634#define stbsp__ddmultlo(oh, ol, xh, xl, yh, yl) ol = ol + (xh * yl + xl * yh);
1636#define stbsp__ddmultlos(oh, ol, xh, yl) ol = ol + (xh * yl);
1638static void stbsp__raise_to_power10(
double *ohi,
double *olo,
double d, stbsp__int32 power)
1641 if ((power >= 0) && (power <= 22)) {
1642 stbsp__ddmulthi(ph, pl, d, stbsp__bot[power]);
1644 stbsp__int32 e, et, eb;
1650 et = (e * 0x2c9) >> 14;
1660 stbsp__ddmulthi(ph, pl, d, stbsp__negbot[eb]);
1661 stbsp__ddmultlos(ph, pl, d, stbsp__negboterr[eb]);
1664 stbsp__ddrenorm(ph, pl);
1666 stbsp__ddmulthi(p2h, p2l, ph, stbsp__negtop[et]);
1667 stbsp__ddmultlo(p2h, p2l, ph, pl, stbsp__negtop[et], stbsp__negtoperr[et]);
1677 stbsp__ddmulthi(ph, pl, d, stbsp__bot[eb]);
1679 stbsp__ddrenorm(ph, pl);
1680 stbsp__ddmulthi(p2h, p2l, ph, stbsp__bot[e]);
1681 stbsp__ddmultlos(p2h, p2l, stbsp__bot[e], pl);
1687 stbsp__ddrenorm(ph, pl);
1689 stbsp__ddmulthi(p2h, p2l, ph, stbsp__top[et]);
1690 stbsp__ddmultlo(p2h, p2l, ph, pl, stbsp__top[et], stbsp__toperr[et]);
1696 stbsp__ddrenorm(ph, pl);
1705static stbsp__int32 stbsp__real_to_str(
char const **start, stbsp__uint32 *len,
char *out, stbsp__int32 *decimal_pos,
double value, stbsp__uint32 frac_digits)
1708 stbsp__int64 bits = 0;
1709 stbsp__int32 expo, e, ng, tens;
1712 STBSP__COPYFP(bits, d);
1713 expo = (stbsp__int32)((bits >> 52) & 2047);
1714 ng = (stbsp__int32)((stbsp__uint64) bits >> 63);
1720 *start = (bits & ((((stbsp__uint64)1) << 52) - 1)) ?
"NaN" :
"Inf";
1721 *decimal_pos = STBSP__SPECIAL;
1728 if (((stbsp__uint64) bits << 1) == 0)
1738 stbsp__int64 v = ((stbsp__uint64)1) << 51;
1739 while ((bits & v) == 0) {
1752 tens = (tens < 0) ? ((tens * 617) / 2048) : (((tens * 1233) / 4096) + 1);
1755 stbsp__raise_to_power10(&ph, &pl, d, 18 - tens);
1758 stbsp__ddtoS64(bits, ph, pl);
1761 if (((stbsp__uint64)bits) >= stbsp__tento19th)
1766 frac_digits = (frac_digits & 0x80000000) ? ((frac_digits & 0x7ffffff) + 1) : (tens + frac_digits);
1767 if ((frac_digits < 24)) {
1768 stbsp__uint32 dg = 1;
1769 if ((stbsp__uint64)bits >= stbsp__powten[9])
1771 while ((stbsp__uint64)bits >= stbsp__powten[dg]) {
1776 if (frac_digits < dg) {
1779 e = dg - frac_digits;
1780 if ((stbsp__uint32)e >= 24)
1782 r = stbsp__powten[e];
1783 bits = bits + (r / 2);
1784 if ((stbsp__uint64)bits >= stbsp__powten[dg])
1795 if (bits <= 0xffffffff)
1801 n = (stbsp__uint32)bits;
1802 while ((n % 1000) == 0)
1815 if (bits >= 100000000) {
1816 n = (stbsp__uint32)(bits % 100000000);
1819 n = (stbsp__uint32)bits;
1824 *(stbsp__uint16 *)out = *(stbsp__uint16 *)&stbsp__digitpair.pair[(n % 100) * 2];
1829 if ((e) && (out[0] ==
'0')) {
1841 *decimal_pos = tens;
1847#undef stbsp__ddmulthi
1848#undef stbsp__ddrenorm
1849#undef stbsp__ddmultlo
1850#undef stbsp__ddmultlos
1851#undef STBSP__SPECIAL
1862#undef STBSP__UNALIGNED
#define STBSP__PUBLICDEF
Definition stb_sprintf.h:176
STBSP__PUBLICDEC int STB_SPRINTF_DECORATE() sprintf(char *buf, char const *fmt,...) STBSP__ATTRIBUTE_FORMAT(2
#define STB_SPRINTF_DECORATE(name)
Definition stb_sprintf.h:205
STBSP__PUBLICDEC int STB_SPRINTF_DECORATE() vsprintf(char *buf, char const *fmt, va_list va)
STBSP__PUBLICDEC void STB_SPRINTF_DECORATE() set_separators(char comma, char period)
#define STBSP__NOTUSED(v)
Definition stb_sprintf.h:193
#define STBSP__PUBLICDEC
Definition stb_sprintf.h:175
#define STBSP__ASAN
Definition stb_sprintf.h:164
STBSP__PUBLICDEC int STB_SPRINTF_DECORATE() STBSP__PUBLICDEC int STB_SPRINTF_DECORATE() STBSP__PUBLICDEC int STB_SPRINTF_DECORATE() vsprintfcb(STBSP_SPRINTFCB *callback, void *user, char *buf, char const *fmt, va_list va)
#define STBSP__ATTRIBUTE_FORMAT(fmt, va)
Definition stb_sprintf.h:187
STBSP__PUBLICDEC int STB_SPRINTF_DECORATE() STBSP__PUBLICDEC int STB_SPRINTF_DECORATE() snprintf(char *buf, int count, char const *fmt,...) STBSP__ATTRIBUTE_FORMAT(3
char * STBSP_SPRINTFCB(const char *buf, void *user, int len)
Definition stb_sprintf.h:202
STBSP__PUBLICDEC int STB_SPRINTF_DECORATE() vsnprintf(char *buf, int count, char const *fmt, va_list va)
#define STB_SPRINTF_MIN
Definition stb_sprintf.h:200