2 ** String formatting for floating-point numbers.
3 ** Copyright (C) 2005-2023 Mike Pall. See Copyright Notice in luajit.h
4 ** Contributed by Peter Cawley.
9 #define lj_strfmt_num_c
15 #include "lj_strfmt.h"
17 /* -- Precomputed tables -------------------------------------------------- */
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)
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
) };
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.
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
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
60 /* -- Helper functions ---------------------------------------------------- */
62 /* Compute the number of digits in the decimal representation of x. */
63 static MSize
ndigits_dec(uint32_t x
)
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
]);
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); }
72 /* Write 9-digit unsigned integer to buffer. */
73 static char *lj_strfmt_wuint9(char *p
, uint32_t u
)
75 uint32_t v
= u
/ 10000, w
;
92 /* -- Extended precision arithmetic --------------------------------------- */
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:
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))}.
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.
116 #define ND_MUL2K_MAX_SHIFT 29
117 #define ND_MUL2K_DIV1E9(val) ((uint32_t)((val) / 1000000000))
119 #define ND_MUL2K_MAX_SHIFT 11
120 #define ND_MUL2K_DIV1E9(val) ((uint32_t)((val) >> 9) / 1953125)
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
)
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;
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;
140 nd
[++ndhi
] = carry_in
; carry_in
= 0;
141 if (start
++ == ndlo
) ++ndlo
;
143 k
-= ND_MUL2K_MAX_SHIFT
;
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;
151 if (carry_in
) nd
[++ndhi
] = carry_in
;
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
)
159 uint32_t ndlo
= 0, stop1
= ~0, stop2
= ~0;
160 /* Performance hacks. */
165 uint32_t s
= lj_ffs(nd
[0]);
166 if (s
>= k
) { nd
[0] >>= k
; return 0; }
171 if (STRFMT_FP(sf
) == STRFMT_FP(STRFMT_T_FP_F
)) {
172 stop1
= 63 - (int32_t)STRFMT_PREC(sf
) / 9;
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;
182 uint32_t i
= ndhi
, carry
= 0;
184 uint32_t val
= nd
[i
];
185 nd
[i
] = (val
>> 9) + carry
;
186 carry
= (val
& 0x1ff) * 1953125;
187 if (i
== ndlo
) break;
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
--; }
200 uint32_t mask
= (1U << k
) - 1, mul
= 1000000000 >> k
, i
= ndhi
, carry
= 0;
202 uint32_t val
= nd
[i
];
203 nd
[i
] = (val
>> k
) + carry
;
204 carry
= (val
& mask
) * mul
;
205 if (i
== ndlo
) break;
208 if (carry
) { ndlo
= (ndlo
- 1) & 0x3f; nd
[ndlo
] = carry
; }
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
)
219 carry
= m
* (ndigits_dec_threshold
[e
- (int32_t)i
*9] + 1);
222 i
= (uint32_t)(64 + f
);
223 carry
= m
* (ndigits_dec_threshold
[e
- f
*9] + 1);
226 uint32_t val
= nd
[i
] + carry
;
227 if (LJ_UNLIKELY(val
>= 1000000000)) {
230 if (LJ_UNLIKELY(i
== ndhi
)) {
231 ndhi
= (ndhi
+ 1) & 0x3f;
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
,
249 char nd9
[9], ref9
[9];
251 if (LJ_UNLIKELY(nd
[ndhi
] != *ref
)) return 0;
252 prec
-= hilen
; ref
--; ndhi
= (ndhi
- 1) & 0x3f;
254 if (LJ_UNLIKELY(nd
[ndhi
] != *ref
)) return 0;
255 prec
-= 9; ref
--; ndhi
= (ndhi
- 1) & 0x3f;
260 lj_assertX(prec
< 9, "bad precision %d", prec
);
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');
266 /* -- Formatted conversions to buffer ------------------------------------- */
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
)
271 MSize width
= STRFMT_WIDTH(sf
), prec
= STRFMT_PREC(sf
), len
;
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
= ' ';
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
= ' ';
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
)) {
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
= ' ';
302 t
.u32
.hi
|= 0x100000;
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
);
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));
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
++ = ' ';
329 if (prefix
) *p
++ = prefix
;
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';
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
;
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; }
345 *p
++ = hexdig
[16]; /* p or P */
346 *p
++ = eprefix
; /* + or - */
347 p
= lj_strfmt_wint(p
, e
);
349 /* %e or %f or %g - begin by converting n to "nd" format. */
351 uint32_t ndhi
= 0, ndlo
, i
;
352 int32_t e
= (t
.u32
.hi
>> 20) & 0x7ff, ndebias
= 0;
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). */
361 prec
^= (uint32_t)((int32_t)prec
>> 31);
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
:
373 e
= (t
.u32
.hi
>> 20) & 0x7ff;
377 nd
[0] = t
.u32
.hi
& 0xfffff;
378 if (e
== 0) e
++; else nd
[0] |= 0x100000;
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
);
390 #error "ND_MUL2K_MAX_SHIFT too small"
394 ndhi
= nd_mul2k(nd
, ndhi
, (uint32_t)e
, 0, sf
);
397 ndlo
= nd_div2k(nd
, ndhi
, (uint32_t)-e
, sf
);
398 if (ndhi
&& !nd
[ndhi
]) ndhi
--;
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). */
406 if (ndlo
&& !nd
[ndhi
]) {
407 ndhi
= 64; do {} while (!nd
[--ndhi
]);
410 hilen
= ndigits_dec(nd
[ndhi
]);
411 nde
+= ndhi
* 9 + hilen
;
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 rounding 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.
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 lj_assertG_(G(sbufL(sb
)), 0 <= eidx
&& eidx
< 128, "bad eidx %d", eidx
);
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))) {
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
]));
439 if ((sf
& STRFMT_T_FP_F
)) {
441 if ((int32_t)prec
>= nde
&& nde
>= -4) {
442 if (nde
< 0) ndhi
= 0;
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. */
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') {
456 if (ndlo
== ndhi
) { prec
= 0; break; }
457 ndlo
= (ndlo
+ 1) & 0x3f;
458 lj_strfmt_wuint9(tail
, nd
[ndlo
]);
465 /* Make nde non-negative. */
469 len
= 3 + prec
+ (prefix
!= 0) + ndigits_dec((uint32_t)nde
) + (nde
< 10)
470 + ((prec
| (sf
& STRFMT_F_ALT
)) != 0);
471 if (!p
) p
= lj_buf_more(sb
, (width
> len
? width
: len
) + 5);
472 if (!(sf
& (STRFMT_F_LEFT
| STRFMT_F_ZERO
))) {
473 while (width
-- > len
) *p
++ = ' ';
475 if (prefix
) *p
++ = prefix
;
476 if ((sf
& (STRFMT_F_LEFT
| STRFMT_F_ZERO
)) == STRFMT_F_ZERO
) {
477 while (width
-- > len
) *p
++ = '0';
479 q
= lj_strfmt_wint(p
+ 1, nd
[ndhi
]);
480 p
[0] = p
[1]; /* Put leading digit in the correct place. */
481 if ((prec
| (sf
& STRFMT_F_ALT
))) {
482 /* Emit fractional part. */
484 prec
-= (MSize
)(q
- p
); p
= q
; /* Account for digits already emitted. */
485 /* Then emit chunks of 9 digits (this may emit 8 digits too many). */
486 for (i
= ndhi
; (int32_t)prec
> 0 && i
!= ndlo
; prec
-= 9) {
488 p
= lj_strfmt_wuint9(p
, nd
[i
]);
490 if ((sf
& STRFMT_T_FP_F
) && !(sf
& STRFMT_F_ALT
)) {
491 /* %g (and not %#g) - strip trailing zeroes. */
492 p
+= (int32_t)prec
& ((int32_t)prec
>> 31);
493 while (p
[-1] == '0') p
--;
494 if (p
[-1] == '.') p
--;
496 /* %e (or %#g) - emit trailing zeroes. */
497 while ((int32_t)prec
> 0) { *p
++ = '0'; prec
--; }
503 *p
++ = (sf
& STRFMT_F_UPPER
) ? 'E' : 'e';
504 *p
++ = eprefix
; /* + or - */
505 if (nde
< 10) *p
++ = '0'; /* Always at least two digits of exponent. */
506 p
= lj_strfmt_wint(p
, nde
);
508 /* %f (or, shortly, %g in %f style) */
509 if (prec
< (MSize
)(0x3f & -(int32_t)ndlo
) * 9) {
510 /* Precision is sufficiently low as to maybe require rounding. */
511 ndhi
= nd_add_m10e(nd
, ndhi
, 5, 0 - prec
- 1);
514 if ((sf
& STRFMT_T_FP_E
) && !(sf
& STRFMT_F_ALT
) && prec
&& width
) {
515 /* Decrease precision in order to strip trailing zeroes. */
517 /* nd has a fractional part; we need to look at its digits. */
519 uint32_t maxprec
= (64 - ndlo
) * 9;
520 if (prec
>= maxprec
) prec
= maxprec
;
521 else ndlo
= 64 - (prec
+ 8) / 9;
522 i
= prec
- ((63 - ndlo
) * 9);
523 lj_strfmt_wuint9(tail
, nd
[ndlo
]);
524 while (prec
&& tail
[--i
] == '0') {
527 if (ndlo
== 63) { prec
= 0; break; }
528 lj_strfmt_wuint9(tail
, nd
[++ndlo
]);
533 /* nd has no fractional part, so precision goes straight to zero. */
537 len
= ndhi
* 9 + ndigits_dec(nd
[ndhi
]) + prec
+ (prefix
!= 0)
538 + ((prec
| (sf
& STRFMT_F_ALT
)) != 0);
539 if (!p
) p
= lj_buf_more(sb
, (width
> len
? width
: len
) + 8);
540 if (!(sf
& (STRFMT_F_LEFT
| STRFMT_F_ZERO
))) {
541 while (width
-- > len
) *p
++ = ' ';
543 if (prefix
) *p
++ = prefix
;
544 if ((sf
& (STRFMT_F_LEFT
| STRFMT_F_ZERO
)) == STRFMT_F_ZERO
) {
545 while (width
-- > len
) *p
++ = '0';
547 /* Emit integer part. */
548 p
= lj_strfmt_wint(p
, nd
[ndhi
]);
550 while (i
) p
= lj_strfmt_wuint9(p
, nd
[--i
]);
551 if ((prec
| (sf
& STRFMT_F_ALT
))) {
552 /* Emit fractional part. */
554 /* Emit chunks of 9 digits (this may emit 8 digits too many). */
555 while ((int32_t)prec
> 0 && i
!= ndlo
) {
557 p
= lj_strfmt_wuint9(p
, nd
[i
]);
560 if ((sf
& STRFMT_T_FP_E
) && !(sf
& STRFMT_F_ALT
)) {
561 /* %g (and not %#g) - strip trailing zeroes. */
562 p
+= (int32_t)prec
& ((int32_t)prec
>> 31);
563 while (p
[-1] == '0') p
--;
564 if (p
[-1] == '.') p
--;
566 /* %f (or %#g) - emit trailing zeroes. */
567 while ((int32_t)prec
> 0) { *p
++ = '0'; prec
--; }
573 if ((sf
& STRFMT_F_LEFT
)) while (width
-- > len
) *p
++ = ' ';
577 /* Add formatted floating-point number to buffer. */
578 SBuf
*lj_strfmt_putfnum(SBuf
*sb
, SFormat sf
, lua_Number n
)
580 sb
->w
= lj_strfmt_wfnum(sb
, sf
, n
, NULL
);
584 /* -- Conversions to strings ---------------------------------------------- */
586 /* Convert number to string. */
587 GCstr
* LJ_FASTCALL
lj_strfmt_num(lua_State
*L
, cTValue
*o
)
589 char buf
[STRFMT_MAXBUF_NUM
];
590 MSize len
= (MSize
)(lj_strfmt_wfnum(NULL
, STRFMT_G14
, o
->n
, buf
) - buf
);
591 return lj_str_new(L
, buf
, len
);