lj_strfmt_num.c (20353B)
1 /* 2 ** String formatting for floating-point numbers. 3 ** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h 4 ** Contributed by Peter Cawley. 5 */ 6 7 #include <stdio.h> 8 9 #define lj_strfmt_num_c 10 #define LUA_CORE 11 12 #include "lj_obj.h" 13 #include "lj_buf.h" 14 #include "lj_str.h" 15 #include "lj_strfmt.h" 16 17 /* -- Precomputed tables -------------------------------------------------- */ 18 19 /* Rescale factors to push the exponent of a number towards zero. */ 20 #define RESCALE_EXPONENTS(P, N) \ 21 P(308), P(289), P(270), P(250), P(231), P(212), P(193), P(173), P(154), \ 22 P(135), P(115), P(96), P(77), P(58), P(38), P(0), P(0), P(0), N(39), N(58), \ 23 N(77), N(96), N(116), N(135), N(154), N(174), N(193), N(212), N(231), \ 24 N(251), N(270), N(289) 25 26 #define ONE_E_P(X) 1e+0 ## X 27 #define ONE_E_N(X) 1e-0 ## X 28 static const int16_t rescale_e[] = { RESCALE_EXPONENTS(-, +) }; 29 static const double rescale_n[] = { RESCALE_EXPONENTS(ONE_E_P, ONE_E_N) }; 30 #undef ONE_E_N 31 #undef ONE_E_P 32 33 /* 34 ** For p in range -70 through 57, this table encodes pairs (m, e) such that 35 ** 4*2^p <= (uint8_t)m*10^e, and is the smallest value for which this holds. 36 */ 37 static const int8_t four_ulp_m_e[] = { 38 34, -21, 68, -21, 14, -20, 28, -20, 55, -20, 2, -19, 3, -19, 5, -19, 9, -19, 39 -82, -18, 35, -18, 7, -17, -117, -17, 28, -17, 56, -17, 112, -16, -33, -16, 40 45, -16, 89, -16, -78, -15, 36, -15, 72, -15, -113, -14, 29, -14, 57, -14, 41 114, -13, -28, -13, 46, -13, 91, -12, -74, -12, 37, -12, 73, -12, 15, -11, 3, 42 -11, 59, -11, 2, -10, 3, -10, 5, -10, 1, -9, -69, -9, 38, -9, 75, -9, 15, -7, 43 3, -7, 6, -7, 12, -6, -17, -7, 48, -7, 96, -7, -65, -6, 39, -6, 77, -6, -103, 44 -5, 31, -5, 62, -5, 123, -4, -11, -4, 49, -4, 98, -4, -60, -3, 4, -2, 79, -3, 45 16, -2, 32, -2, 63, -2, 2, -1, 25, 0, 5, 1, 1, 2, 2, 2, 4, 2, 8, 2, 16, 2, 46 32, 2, 64, 2, -128, 2, 26, 2, 52, 2, 103, 3, -51, 3, 41, 4, 82, 4, -92, 4, 47 33, 4, 66, 4, -124, 5, 27, 5, 53, 5, 105, 6, 21, 6, 42, 6, 84, 6, 17, 7, 34, 48 7, 68, 7, 2, 8, 3, 8, 6, 8, 108, 9, -41, 9, 43, 10, 86, 9, -84, 10, 35, 10, 49 69, 10, -118, 11, 28, 11, 55, 12, 11, 13, 22, 13, 44, 13, 88, 13, -80, 13, 50 36, 13, 71, 13, -115, 14, 29, 14, 57, 14, 113, 15, -30, 15, 46, 15, 91, 15, 51 19, 16, 37, 16, 73, 16, 2, 17, 3, 17, 6, 17 52 }; 53 54 /* min(2^32-1, 10^e-1) for e in range 0 through 10 */ 55 static uint32_t ndigits_dec_threshold[] = { 56 0, 9U, 99U, 999U, 9999U, 99999U, 999999U, 57 9999999U, 99999999U, 999999999U, 0xffffffffU 58 }; 59 60 /* -- Helper functions ---------------------------------------------------- */ 61 62 /* Compute the number of digits in the decimal representation of x. */ 63 static MSize ndigits_dec(uint32_t x) 64 { 65 MSize t = ((lj_fls(x | 1) * 77) >> 8) + 1; /* 2^8/77 is roughly log2(10) */ 66 return t + (x > ndigits_dec_threshold[t]); 67 } 68 69 #define WINT_R(x, sh, sc) \ 70 { uint32_t d = (x*(((1<<sh)+sc-1)/sc))>>sh; x -= d*sc; *p++ = (char)('0'+d); } 71 72 /* Write 9-digit unsigned integer to buffer. */ 73 static char *lj_strfmt_wuint9(char *p, uint32_t u) 74 { 75 uint32_t v = u / 10000, w; 76 u -= v * 10000; 77 w = v / 10000; 78 v -= w * 10000; 79 *p++ = (char)('0'+w); 80 WINT_R(v, 23, 1000) 81 WINT_R(v, 12, 100) 82 WINT_R(v, 10, 10) 83 *p++ = (char)('0'+v); 84 WINT_R(u, 23, 1000) 85 WINT_R(u, 12, 100) 86 WINT_R(u, 10, 10) 87 *p++ = (char)('0'+u); 88 return p; 89 } 90 #undef WINT_R 91 92 /* -- Extended precision arithmetic --------------------------------------- */ 93 94 /* 95 ** The "nd" format is a fixed-precision decimal representation for numbers. It 96 ** consists of up to 64 uint32_t values, with each uint32_t storing a value 97 ** in the range [0, 1e9). A number in "nd" format consists of three variables: 98 ** 99 ** uint32_t nd[64]; 100 ** uint32_t ndlo; 101 ** uint32_t ndhi; 102 ** 103 ** The integral part of the number is stored in nd[0 ... ndhi], the value of 104 ** which is sum{i in [0, ndhi] | nd[i] * 10^(9*i)}. If the fractional part of 105 ** the number is zero, ndlo is zero. Otherwise, the fractional part is stored 106 ** in nd[ndlo ... 63], the value of which is taken to be 107 ** sum{i in [ndlo, 63] | nd[i] * 10^(9*(i-64))}. 108 ** 109 ** If the array part had 128 elements rather than 64, then every double would 110 ** have an exact representation in "nd" format. With 64 elements, all integral 111 ** doubles have an exact representation, and all non-integral doubles have 112 ** enough digits to make both %.99e and %.99f do the right thing. 113 */ 114 115 #if LJ_64 116 #define ND_MUL2K_MAX_SHIFT 29 117 #define ND_MUL2K_DIV1E9(val) ((uint32_t)((val) / 1000000000)) 118 #else 119 #define ND_MUL2K_MAX_SHIFT 11 120 #define ND_MUL2K_DIV1E9(val) ((uint32_t)((val) >> 9) / 1953125) 121 #endif 122 123 /* Multiply nd by 2^k and add carry_in (ndlo is assumed to be zero). */ 124 static uint32_t nd_mul2k(uint32_t* nd, uint32_t ndhi, uint32_t k, 125 uint32_t carry_in, SFormat sf) 126 { 127 uint32_t i, ndlo = 0, start = 1; 128 /* Performance hacks. */ 129 if (k > ND_MUL2K_MAX_SHIFT*2 && STRFMT_FP(sf) != STRFMT_FP(STRFMT_T_FP_F)) { 130 start = ndhi - (STRFMT_PREC(sf) + 17) / 8; 131 } 132 /* Real logic. */ 133 while (k >= ND_MUL2K_MAX_SHIFT) { 134 for (i = ndlo; i <= ndhi; i++) { 135 uint64_t val = ((uint64_t)nd[i] << ND_MUL2K_MAX_SHIFT) | carry_in; 136 carry_in = ND_MUL2K_DIV1E9(val); 137 nd[i] = (uint32_t)val - carry_in * 1000000000; 138 } 139 if (carry_in) { 140 nd[++ndhi] = carry_in; carry_in = 0; 141 if(start++ == ndlo) ++ndlo; 142 } 143 k -= ND_MUL2K_MAX_SHIFT; 144 } 145 if (k) { 146 for (i = ndlo; i <= ndhi; i++) { 147 uint64_t val = ((uint64_t)nd[i] << k) | carry_in; 148 carry_in = ND_MUL2K_DIV1E9(val); 149 nd[i] = (uint32_t)val - carry_in * 1000000000; 150 } 151 if (carry_in) nd[++ndhi] = carry_in; 152 } 153 return ndhi; 154 } 155 156 /* Divide nd by 2^k (ndlo is assumed to be zero). */ 157 static uint32_t nd_div2k(uint32_t* nd, uint32_t ndhi, uint32_t k, SFormat sf) 158 { 159 uint32_t ndlo = 0, stop1 = ~0, stop2 = ~0; 160 /* Performance hacks. */ 161 if (!ndhi) { 162 if (!nd[0]) { 163 return 0; 164 } else { 165 uint32_t s = lj_ffs(nd[0]); 166 if (s >= k) { nd[0] >>= k; return 0; } 167 nd[0] >>= s; k -= s; 168 } 169 } 170 if (k > 18) { 171 if (STRFMT_FP(sf) == STRFMT_FP(STRFMT_T_FP_F)) { 172 stop1 = 63 - (int32_t)STRFMT_PREC(sf) / 9; 173 } else { 174 int32_t floorlog2 = ndhi * 29 + lj_fls(nd[ndhi]) - k; 175 int32_t floorlog10 = (int32_t)(floorlog2 * 0.30102999566398114); 176 stop1 = 62 + (floorlog10 - (int32_t)STRFMT_PREC(sf)) / 9; 177 stop2 = 61 + ndhi - (int32_t)STRFMT_PREC(sf) / 8; 178 } 179 } 180 /* Real logic. */ 181 while (k >= 9) { 182 uint32_t i = ndhi, carry = 0; 183 for (;;) { 184 uint32_t val = nd[i]; 185 nd[i] = (val >> 9) + carry; 186 carry = (val & 0x1ff) * 1953125; 187 if (i == ndlo) break; 188 i = (i - 1) & 0x3f; 189 } 190 if (ndlo != stop1 && ndlo != stop2) { 191 if (carry) { ndlo = (ndlo - 1) & 0x3f; nd[ndlo] = carry; } 192 if (!nd[ndhi]) { ndhi = (ndhi - 1) & 0x3f; stop2--; } 193 } else if (!nd[ndhi]) { 194 if (ndhi != ndlo) { ndhi = (ndhi - 1) & 0x3f; stop2--; } 195 else return ndlo; 196 } 197 k -= 9; 198 } 199 if (k) { 200 uint32_t mask = (1U << k) - 1, mul = 1000000000 >> k, i = ndhi, carry = 0; 201 for (;;) { 202 uint32_t val = nd[i]; 203 nd[i] = (val >> k) + carry; 204 carry = (val & mask) * mul; 205 if (i == ndlo) break; 206 i = (i - 1) & 0x3f; 207 } 208 if (carry) { ndlo = (ndlo - 1) & 0x3f; nd[ndlo] = carry; } 209 } 210 return ndlo; 211 } 212 213 /* Add m*10^e to nd (assumes ndlo <= e/9 <= ndhi and 0 <= m <= 9). */ 214 static uint32_t nd_add_m10e(uint32_t* nd, uint32_t ndhi, uint8_t m, int32_t e) 215 { 216 uint32_t i, carry; 217 if (e >= 0) { 218 i = (uint32_t)e/9; 219 carry = m * (ndigits_dec_threshold[e - (int32_t)i*9] + 1); 220 } else { 221 int32_t f = (e-8)/9; 222 i = (uint32_t)(64 + f); 223 carry = m * (ndigits_dec_threshold[e - f*9] + 1); 224 } 225 for (;;) { 226 uint32_t val = nd[i] + carry; 227 if (LJ_UNLIKELY(val >= 1000000000)) { 228 val -= 1000000000; 229 nd[i] = val; 230 if (LJ_UNLIKELY(i == ndhi)) { 231 ndhi = (ndhi + 1) & 0x3f; 232 nd[ndhi] = 1; 233 break; 234 } 235 carry = 1; 236 i = (i + 1) & 0x3f; 237 } else { 238 nd[i] = val; 239 break; 240 } 241 } 242 return ndhi; 243 } 244 245 /* Test whether two "nd" values are equal in their most significant digits. */ 246 static int nd_similar(uint32_t* nd, uint32_t ndhi, uint32_t* ref, MSize hilen, 247 MSize prec) 248 { 249 char nd9[9], ref9[9]; 250 if (hilen <= prec) { 251 if (LJ_UNLIKELY(nd[ndhi] != *ref)) return 0; 252 prec -= hilen; ref--; ndhi = (ndhi - 1) & 0x3f; 253 if (prec >= 9) { 254 if (LJ_UNLIKELY(nd[ndhi] != *ref)) return 0; 255 prec -= 9; ref--; ndhi = (ndhi - 1) & 0x3f; 256 } 257 } else { 258 prec -= hilen - 9; 259 } 260 lua_assert(prec < 9); 261 lj_strfmt_wuint9(nd9, nd[ndhi]); 262 lj_strfmt_wuint9(ref9, *ref); 263 return !memcmp(nd9, ref9, prec) && (nd9[prec] < '5') == (ref9[prec] < '5'); 264 } 265 266 /* -- Formatted conversions to buffer ------------------------------------- */ 267 268 /* Write formatted floating-point number to either sb or p. */ 269 static char *lj_strfmt_wfnum(SBuf *sb, SFormat sf, lua_Number n, char *p) 270 { 271 MSize width = STRFMT_WIDTH(sf), prec = STRFMT_PREC(sf), len; 272 TValue t; 273 t.n = n; 274 if (LJ_UNLIKELY((t.u32.hi << 1) >= 0xffe00000)) { 275 /* Handle non-finite values uniformly for %a, %e, %f, %g. */ 276 int prefix = 0, ch = (sf & STRFMT_F_UPPER) ? 0x202020 : 0; 277 if (((t.u32.hi & 0x000fffff) | t.u32.lo) != 0) { 278 ch ^= ('n' << 16) | ('a' << 8) | 'n'; 279 if ((sf & STRFMT_F_SPACE)) prefix = ' '; 280 } else { 281 ch ^= ('i' << 16) | ('n' << 8) | 'f'; 282 if ((t.u32.hi & 0x80000000)) prefix = '-'; 283 else if ((sf & STRFMT_F_PLUS)) prefix = '+'; 284 else if ((sf & STRFMT_F_SPACE)) prefix = ' '; 285 } 286 len = 3 + (prefix != 0); 287 if (!p) p = lj_buf_more(sb, width > len ? width : len); 288 if (!(sf & STRFMT_F_LEFT)) while (width-- > len) *p++ = ' '; 289 if (prefix) *p++ = prefix; 290 *p++ = (char)(ch >> 16); *p++ = (char)(ch >> 8); *p++ = (char)ch; 291 } else if (STRFMT_FP(sf) == STRFMT_FP(STRFMT_T_FP_A)) { 292 /* %a */ 293 const char *hexdig = (sf & STRFMT_F_UPPER) ? "0123456789ABCDEFPX" 294 : "0123456789abcdefpx"; 295 int32_t e = (t.u32.hi >> 20) & 0x7ff; 296 char prefix = 0, eprefix = '+'; 297 if (t.u32.hi & 0x80000000) prefix = '-'; 298 else if ((sf & STRFMT_F_PLUS)) prefix = '+'; 299 else if ((sf & STRFMT_F_SPACE)) prefix = ' '; 300 t.u32.hi &= 0xfffff; 301 if (e) { 302 t.u32.hi |= 0x100000; 303 e -= 1023; 304 } else if (t.u32.lo | t.u32.hi) { 305 /* Non-zero denormal - normalise it. */ 306 uint32_t shift = t.u32.hi ? 20-lj_fls(t.u32.hi) : 52-lj_fls(t.u32.lo); 307 e = -1022 - shift; 308 t.u64 <<= shift; 309 } 310 /* abs(n) == t.u64 * 2^(e - 52) */ 311 /* If n != 0, bit 52 of t.u64 is set, and is the highest set bit. */ 312 if ((int32_t)prec < 0) { 313 /* Default precision: use smallest precision giving exact result. */ 314 prec = t.u32.lo ? 13-lj_ffs(t.u32.lo)/4 : 5-lj_ffs(t.u32.hi|0x100000)/4; 315 } else if (prec < 13) { 316 /* Precision is sufficiently low as to maybe require rounding. */ 317 t.u64 += (((uint64_t)1) << (51 - prec*4)); 318 } 319 if (e < 0) { 320 eprefix = '-'; 321 e = -e; 322 } 323 len = 5 + ndigits_dec((uint32_t)e) + prec + (prefix != 0) 324 + ((prec | (sf & STRFMT_F_ALT)) != 0); 325 if (!p) p = lj_buf_more(sb, width > len ? width : len); 326 if (!(sf & (STRFMT_F_LEFT | STRFMT_F_ZERO))) { 327 while (width-- > len) *p++ = ' '; 328 } 329 if (prefix) *p++ = prefix; 330 *p++ = '0'; 331 *p++ = hexdig[17]; /* x or X */ 332 if ((sf & (STRFMT_F_LEFT | STRFMT_F_ZERO)) == STRFMT_F_ZERO) { 333 while (width-- > len) *p++ = '0'; 334 } 335 *p++ = '0' + (t.u32.hi >> 20); /* Usually '1', sometimes '0' or '2'. */ 336 if ((prec | (sf & STRFMT_F_ALT))) { 337 /* Emit fractional part. */ 338 char *q = p + 1 + prec; 339 *p = '.'; 340 if (prec < 13) t.u64 >>= (52 - prec*4); 341 else while (prec > 13) p[prec--] = '0'; 342 while (prec) { p[prec--] = hexdig[t.u64 & 15]; t.u64 >>= 4; } 343 p = q; 344 } 345 *p++ = hexdig[16]; /* p or P */ 346 *p++ = eprefix; /* + or - */ 347 p = lj_strfmt_wint(p, e); 348 } else { 349 /* %e or %f or %g - begin by converting n to "nd" format. */ 350 uint32_t nd[64]; 351 uint32_t ndhi = 0, ndlo, i; 352 int32_t e = (t.u32.hi >> 20) & 0x7ff, ndebias = 0; 353 char prefix = 0, *q; 354 if (t.u32.hi & 0x80000000) prefix = '-'; 355 else if ((sf & STRFMT_F_PLUS)) prefix = '+'; 356 else if ((sf & STRFMT_F_SPACE)) prefix = ' '; 357 prec += ((int32_t)prec >> 31) & 7; /* Default precision is 6. */ 358 if (STRFMT_FP(sf) == STRFMT_FP(STRFMT_T_FP_G)) { 359 /* %g - decrement precision if non-zero (to make it like %e). */ 360 prec--; 361 prec ^= (uint32_t)((int32_t)prec >> 31); 362 } 363 if ((sf & STRFMT_T_FP_E) && prec < 14 && n != 0) { 364 /* Precision is sufficiently low that rescaling will probably work. */ 365 if ((ndebias = rescale_e[e >> 6])) { 366 t.n = n * rescale_n[e >> 6]; 367 if (LJ_UNLIKELY(!e)) t.n *= 1e10, ndebias -= 10; 368 t.u64 -= 2; /* Convert 2ulp below (later we convert 2ulp above). */ 369 nd[0] = 0x100000 | (t.u32.hi & 0xfffff); 370 e = ((t.u32.hi >> 20) & 0x7ff) - 1075 - (ND_MUL2K_MAX_SHIFT < 29); 371 goto load_t_lo; rescale_failed: 372 t.n = n; 373 e = (t.u32.hi >> 20) & 0x7ff; 374 ndebias = ndhi = 0; 375 } 376 } 377 nd[0] = t.u32.hi & 0xfffff; 378 if (e == 0) e++; else nd[0] |= 0x100000; 379 e -= 1043; 380 if (t.u32.lo) { 381 e -= 32 + (ND_MUL2K_MAX_SHIFT < 29); load_t_lo: 382 #if ND_MUL2K_MAX_SHIFT >= 29 383 nd[0] = (nd[0] << 3) | (t.u32.lo >> 29); 384 ndhi = nd_mul2k(nd, ndhi, 29, t.u32.lo & 0x1fffffff, sf); 385 #elif ND_MUL2K_MAX_SHIFT >= 11 386 ndhi = nd_mul2k(nd, ndhi, 11, t.u32.lo >> 21, sf); 387 ndhi = nd_mul2k(nd, ndhi, 11, (t.u32.lo >> 10) & 0x7ff, sf); 388 ndhi = nd_mul2k(nd, ndhi, 11, (t.u32.lo << 1) & 0x7ff, sf); 389 #else 390 #error "ND_MUL2K_MAX_SHIFT too small" 391 #endif 392 } 393 if (e >= 0) { 394 ndhi = nd_mul2k(nd, ndhi, (uint32_t)e, 0, sf); 395 ndlo = 0; 396 } else { 397 ndlo = nd_div2k(nd, ndhi, (uint32_t)-e, sf); 398 if (ndhi && !nd[ndhi]) ndhi--; 399 } 400 /* abs(n) == nd * 10^ndebias (for slightly loose interpretation of ==) */ 401 if ((sf & STRFMT_T_FP_E)) { 402 /* %e or %g - assume %e and start by calculating nd's exponent (nde). */ 403 char eprefix = '+'; 404 int32_t nde = -1; 405 MSize hilen; 406 if (ndlo && !nd[ndhi]) { 407 ndhi = 64; do {} while (!nd[--ndhi]); 408 nde -= 64 * 9; 409 } 410 hilen = ndigits_dec(nd[ndhi]); 411 nde += ndhi * 9 + hilen; 412 if (ndebias) { 413 /* 414 ** Rescaling was performed, but this introduced some error, and might 415 ** have pushed us across a rounding boundary. We check whether this 416 ** error affected the result by introducing even more error (2ulp in 417 ** either direction), and seeing whether a roundary boundary was 418 ** crossed. Having already converted the -2ulp case, we save off its 419 ** most significant digits, convert the +2ulp case, and compare them. 420 */ 421 int32_t eidx = e + 70 + (ND_MUL2K_MAX_SHIFT < 29) 422 + (t.u32.lo >= 0xfffffffe && !(~t.u32.hi << 12)); 423 const int8_t *m_e = four_ulp_m_e + eidx * 2; 424 lua_assert(0 <= eidx && eidx < 128); 425 nd[33] = nd[ndhi]; 426 nd[32] = nd[(ndhi - 1) & 0x3f]; 427 nd[31] = nd[(ndhi - 2) & 0x3f]; 428 nd_add_m10e(nd, ndhi, (uint8_t)*m_e, m_e[1]); 429 if (LJ_UNLIKELY(!nd_similar(nd, ndhi, nd + 33, hilen, prec + 1))) { 430 goto rescale_failed; 431 } 432 } 433 if ((int32_t)(prec - nde) < (0x3f & -(int32_t)ndlo) * 9) { 434 /* Precision is sufficiently low as to maybe require rounding. */ 435 ndhi = nd_add_m10e(nd, ndhi, 5, nde - prec - 1); 436 nde += (hilen != ndigits_dec(nd[ndhi])); 437 } 438 nde += ndebias; 439 if ((sf & STRFMT_T_FP_F)) { 440 /* %g */ 441 if ((int32_t)prec >= nde && nde >= -4) { 442 if (nde < 0) ndhi = 0; 443 prec -= nde; 444 goto g_format_like_f; 445 } else if (!(sf & STRFMT_F_ALT) && prec && width > 5) { 446 /* Decrease precision in order to strip trailing zeroes. */ 447 char tail[9]; 448 uint32_t maxprec = hilen - 1 + ((ndhi - ndlo) & 0x3f) * 9; 449 if (prec >= maxprec) prec = maxprec; 450 else ndlo = (ndhi - (((int32_t)(prec - hilen) + 9) / 9)) & 0x3f; 451 i = prec - hilen - (((ndhi - ndlo) & 0x3f) * 9) + 10; 452 lj_strfmt_wuint9(tail, nd[ndlo]); 453 while (prec && tail[--i] == '0') { 454 prec--; 455 if (!i) { 456 if (ndlo == ndhi) { prec = 0; break; } 457 lj_strfmt_wuint9(tail, nd[++ndlo]); 458 i = 9; 459 } 460 } 461 } 462 } 463 if (nde < 0) { 464 /* Make nde non-negative. */ 465 eprefix = '-'; 466 nde = -nde; 467 } 468 len = 3 + prec + (prefix != 0) + ndigits_dec((uint32_t)nde) + (nde < 10) 469 + ((prec | (sf & STRFMT_F_ALT)) != 0); 470 if (!p) p = lj_buf_more(sb, (width > len ? width : len) + 5); 471 if (!(sf & (STRFMT_F_LEFT | STRFMT_F_ZERO))) { 472 while (width-- > len) *p++ = ' '; 473 } 474 if (prefix) *p++ = prefix; 475 if ((sf & (STRFMT_F_LEFT | STRFMT_F_ZERO)) == STRFMT_F_ZERO) { 476 while (width-- > len) *p++ = '0'; 477 } 478 q = lj_strfmt_wint(p + 1, nd[ndhi]); 479 p[0] = p[1]; /* Put leading digit in the correct place. */ 480 if ((prec | (sf & STRFMT_F_ALT))) { 481 /* Emit fractional part. */ 482 p[1] = '.'; p += 2; 483 prec -= (MSize)(q - p); p = q; /* Account for digits already emitted. */ 484 /* Then emit chunks of 9 digits (this may emit 8 digits too many). */ 485 for (i = ndhi; (int32_t)prec > 0 && i != ndlo; prec -= 9) { 486 i = (i - 1) & 0x3f; 487 p = lj_strfmt_wuint9(p, nd[i]); 488 } 489 if ((sf & STRFMT_T_FP_F) && !(sf & STRFMT_F_ALT)) { 490 /* %g (and not %#g) - strip trailing zeroes. */ 491 p += (int32_t)prec & ((int32_t)prec >> 31); 492 while (p[-1] == '0') p--; 493 if (p[-1] == '.') p--; 494 } else { 495 /* %e (or %#g) - emit trailing zeroes. */ 496 while ((int32_t)prec > 0) { *p++ = '0'; prec--; } 497 p += (int32_t)prec; 498 } 499 } else { 500 p++; 501 } 502 *p++ = (sf & STRFMT_F_UPPER) ? 'E' : 'e'; 503 *p++ = eprefix; /* + or - */ 504 if (nde < 10) *p++ = '0'; /* Always at least two digits of exponent. */ 505 p = lj_strfmt_wint(p, nde); 506 } else { 507 /* %f (or, shortly, %g in %f style) */ 508 if (prec < (MSize)(0x3f & -(int32_t)ndlo) * 9) { 509 /* Precision is sufficiently low as to maybe require rounding. */ 510 ndhi = nd_add_m10e(nd, ndhi, 5, 0 - prec - 1); 511 } 512 g_format_like_f: 513 if ((sf & STRFMT_T_FP_E) && !(sf & STRFMT_F_ALT) && prec && width) { 514 /* Decrease precision in order to strip trailing zeroes. */ 515 if (ndlo) { 516 /* nd has a fractional part; we need to look at its digits. */ 517 char tail[9]; 518 uint32_t maxprec = (64 - ndlo) * 9; 519 if (prec >= maxprec) prec = maxprec; 520 else ndlo = 64 - (prec + 8) / 9; 521 i = prec - ((63 - ndlo) * 9); 522 lj_strfmt_wuint9(tail, nd[ndlo]); 523 while (prec && tail[--i] == '0') { 524 prec--; 525 if (!i) { 526 if (ndlo == 63) { prec = 0; break; } 527 lj_strfmt_wuint9(tail, nd[++ndlo]); 528 i = 9; 529 } 530 } 531 } else { 532 /* nd has no fractional part, so precision goes straight to zero. */ 533 prec = 0; 534 } 535 } 536 len = ndhi * 9 + ndigits_dec(nd[ndhi]) + prec + (prefix != 0) 537 + ((prec | (sf & STRFMT_F_ALT)) != 0); 538 if (!p) p = lj_buf_more(sb, (width > len ? width : len) + 8); 539 if (!(sf & (STRFMT_F_LEFT | STRFMT_F_ZERO))) { 540 while (width-- > len) *p++ = ' '; 541 } 542 if (prefix) *p++ = prefix; 543 if ((sf & (STRFMT_F_LEFT | STRFMT_F_ZERO)) == STRFMT_F_ZERO) { 544 while (width-- > len) *p++ = '0'; 545 } 546 /* Emit integer part. */ 547 p = lj_strfmt_wint(p, nd[ndhi]); 548 i = ndhi; 549 while (i) p = lj_strfmt_wuint9(p, nd[--i]); 550 if ((prec | (sf & STRFMT_F_ALT))) { 551 /* Emit fractional part. */ 552 *p++ = '.'; 553 /* Emit chunks of 9 digits (this may emit 8 digits too many). */ 554 while ((int32_t)prec > 0 && i != ndlo) { 555 i = (i - 1) & 0x3f; 556 p = lj_strfmt_wuint9(p, nd[i]); 557 prec -= 9; 558 } 559 if ((sf & STRFMT_T_FP_E) && !(sf & STRFMT_F_ALT)) { 560 /* %g (and not %#g) - strip trailing zeroes. */ 561 p += (int32_t)prec & ((int32_t)prec >> 31); 562 while (p[-1] == '0') p--; 563 if (p[-1] == '.') p--; 564 } else { 565 /* %f (or %#g) - emit trailing zeroes. */ 566 while ((int32_t)prec > 0) { *p++ = '0'; prec--; } 567 p += (int32_t)prec; 568 } 569 } 570 } 571 } 572 if ((sf & STRFMT_F_LEFT)) while (width-- > len) *p++ = ' '; 573 return p; 574 } 575 576 /* Add formatted floating-point number to buffer. */ 577 SBuf *lj_strfmt_putfnum(SBuf *sb, SFormat sf, lua_Number n) 578 { 579 setsbufP(sb, lj_strfmt_wfnum(sb, sf, n, NULL)); 580 return sb; 581 } 582 583 /* -- Conversions to strings ---------------------------------------------- */ 584 585 /* Convert number to string. */ 586 GCstr * LJ_FASTCALL lj_strfmt_num(lua_State *L, cTValue *o) 587 { 588 char buf[STRFMT_MAXBUF_NUM]; 589 MSize len = (MSize)(lj_strfmt_wfnum(NULL, STRFMT_G14, o->n, buf) - buf); 590 return lj_str_new(L, buf, len); 591 } 592