1 /*
2 * Number-to-string and string-to-number conversions.
3 *
4 * Slow path number-to-string and string-to-number conversion is based on
5 * a Dragon4 variant, with fast paths for small integers. Big integer
6 * arithmetic is needed for guaranteeing that the conversion is correct
7 * and uses a minimum number of digits. The big number arithmetic has a
8 * fixed maximum size and does not require dynamic allocations.
9 *
10 * See: doc/number-conversion.rst.
11 */
12
13 #include "duk_internal.h"
14
15 #define DUK__IEEE_DOUBLE_EXP_BIAS 1023
16 #define DUK__IEEE_DOUBLE_EXP_MIN (-1022) /* biased exp == 0 -> denormal, exp -1022 */
17
18 #define DUK__DIGITCHAR(x) duk_lc_digits[(x)]
19
20 /*
21 * Tables generated with src/gennumdigits.py.
22 *
23 * duk__str2num_digits_for_radix indicates, for each radix, how many input
24 * digits should be considered significant for string-to-number conversion.
25 * The input is also padded to this many digits to give the Dragon4
26 * conversion enough (apparent) precision to work with.
27 *
28 * duk__str2num_exp_limits indicates, for each radix, the radix-specific
29 * minimum/maximum exponent values (for a Dragon4 integer mantissa)
30 * below and above which the number is guaranteed to underflow to zero
31 * or overflow to Infinity. This allows parsing to keep bigint values
32 * bounded.
33 */
34
35 DUK_LOCAL const duk_uint8_t duk__str2num_digits_for_radix[] = {
36 69, 44, 35, 30, 27, 25, 23, 22, 20, 20, /* 2 to 11 */
37 20, 19, 19, 18, 18, 17, 17, 17, 16, 16, /* 12 to 21 */
38 16, 16, 16, 15, 15, 15, 15, 15, 15, 14, /* 22 to 31 */
39 14, 14, 14, 14, 14 /* 31 to 36 */
40 };
41
42 typedef struct {
43 duk_int16_t upper;
44 duk_int16_t lower;
45 } duk__exp_limits;
46
47 DUK_LOCAL const duk__exp_limits duk__str2num_exp_limits[] = {
48 { 957, -1147 }, { 605, -725 }, { 479, -575 }, { 414, -496 },
49 { 372, -446 }, { 342, -411 }, { 321, -384 }, { 304, -364 },
50 { 291, -346 }, { 279, -334 }, { 268, -323 }, { 260, -312 },
51 { 252, -304 }, { 247, -296 }, { 240, -289 }, { 236, -283 },
52 { 231, -278 }, { 227, -273 }, { 223, -267 }, { 220, -263 },
53 { 216, -260 }, { 213, -256 }, { 210, -253 }, { 208, -249 },
54 { 205, -246 }, { 203, -244 }, { 201, -241 }, { 198, -239 },
55 { 196, -237 }, { 195, -234 }, { 193, -232 }, { 191, -230 },
56 { 190, -228 }, { 188, -226 }, { 187, -225 },
57 };
58
59 /*
60 * Limited functionality bigint implementation.
61 *
62 * Restricted to non-negative numbers with less than 32 * DUK__BI_MAX_PARTS bits,
63 * with the caller responsible for ensuring this is never exceeded. No memory
64 * allocation (except stack) is needed for bigint computation. Operations
65 * have been tailored for number conversion needs.
66 *
67 * Argument order is "assignment order", i.e. target first, then arguments:
68 * x <- y * z --> duk__bi_mul(x, y, z);
69 */
70
71 /* This upper value has been experimentally determined; debug build will check
72 * bigint size with assertions.
73 */
74 #define DUK__BI_MAX_PARTS 37 /* 37x32 = 1184 bits */
75
76 #ifdef DUK_USE_DDDPRINT
77 #define DUK__BI_PRINT(name,x) duk__bi_print((name),(x))
78 #else
79 #define DUK__BI_PRINT(name,x)
80 #endif
81
82 /* Current size is about 152 bytes. */
83 typedef struct {
84 duk_small_int_t n;
85 duk_uint32_t v[DUK__BI_MAX_PARTS]; /* low to high */
86 } duk__bigint;
87
88 #ifdef DUK_USE_DDDPRINT
duk__bi_print(const char * name,duk__bigint * x)89 DUK_LOCAL void duk__bi_print(const char *name, duk__bigint *x) {
90 /* Overestimate required size; debug code so not critical to be tight. */
91 char buf[DUK__BI_MAX_PARTS * 9 + 64];
92 char *p = buf;
93 duk_small_int_t i;
94
95 /* No NUL term checks in this debug code. */
96 p += DUK_SPRINTF(p, "%p n=%ld", (void *) x, (long) x->n);
97 if (x->n == 0) {
98 p += DUK_SPRINTF(p, " 0");
99 }
100 for (i = x->n - 1; i >= 0; i--) {
101 p += DUK_SPRINTF(p, " %08lx", (unsigned long) x->v[i]);
102 }
103
104 DUK_DDD(DUK_DDDPRINT("%s: %s", (const char *) name, (const char *) buf));
105 }
106 #endif
107
108 #ifdef DUK_USE_ASSERTIONS
duk__bi_is_valid(duk__bigint * x)109 DUK_LOCAL duk_small_int_t duk__bi_is_valid(duk__bigint *x) {
110 return (duk_small_int_t)
111 ( ((x->n >= 0) && (x->n <= DUK__BI_MAX_PARTS)) /* is valid size */ &&
112 ((x->n == 0) || (x->v[x->n - 1] != 0)) /* is normalized */ );
113 }
114 #endif
115
duk__bi_normalize(duk__bigint * x)116 DUK_LOCAL void duk__bi_normalize(duk__bigint *x) {
117 duk_small_int_t i;
118
119 for (i = x->n - 1; i >= 0; i--) {
120 if (x->v[i] != 0) {
121 break;
122 }
123 }
124
125 /* Note: if 'x' is zero, x->n becomes 0 here */
126 x->n = i + 1;
127 DUK_ASSERT(duk__bi_is_valid(x));
128 }
129
130 /* x <- y */
duk__bi_copy(duk__bigint * x,duk__bigint * y)131 DUK_LOCAL void duk__bi_copy(duk__bigint *x, duk__bigint *y) {
132 duk_small_int_t n;
133
134 n = y->n;
135 x->n = n;
136 if (n == 0) {
137 return;
138 }
139 DUK_MEMCPY((void *) x->v, (const void *) y->v, (size_t) (sizeof(duk_uint32_t) * n));
140 }
141
duk__bi_set_small(duk__bigint * x,duk_uint32_t v)142 DUK_LOCAL void duk__bi_set_small(duk__bigint *x, duk_uint32_t v) {
143 if (v == 0U) {
144 x->n = 0;
145 } else {
146 x->n = 1;
147 x->v[0] = v;
148 }
149 DUK_ASSERT(duk__bi_is_valid(x));
150 }
151
152 /* Return value: <0 <=> x < y
153 * 0 <=> x == y
154 * >0 <=> x > y
155 */
duk__bi_compare(duk__bigint * x,duk__bigint * y)156 DUK_LOCAL int duk__bi_compare(duk__bigint *x, duk__bigint *y) {
157 duk_small_int_t i, nx, ny;
158 duk_uint32_t tx, ty;
159
160 DUK_ASSERT(duk__bi_is_valid(x));
161 DUK_ASSERT(duk__bi_is_valid(y));
162
163 nx = x->n;
164 ny = y->n;
165 if (nx > ny) {
166 goto ret_gt;
167 }
168 if (nx < ny) {
169 goto ret_lt;
170 }
171 for (i = nx - 1; i >= 0; i--) {
172 tx = x->v[i];
173 ty = y->v[i];
174
175 if (tx > ty) {
176 goto ret_gt;
177 }
178 if (tx < ty) {
179 goto ret_lt;
180 }
181 }
182
183 return 0;
184
185 ret_gt:
186 return 1;
187
188 ret_lt:
189 return -1;
190 }
191
192 /* x <- y + z */
193 #ifdef DUK_USE_64BIT_OPS
duk__bi_add(duk__bigint * x,duk__bigint * y,duk__bigint * z)194 DUK_LOCAL void duk__bi_add(duk__bigint *x, duk__bigint *y, duk__bigint *z) {
195 duk_uint64_t tmp;
196 duk_small_int_t i, ny, nz;
197
198 DUK_ASSERT(duk__bi_is_valid(y));
199 DUK_ASSERT(duk__bi_is_valid(z));
200
201 if (z->n > y->n) {
202 duk__bigint *t;
203 t = y; y = z; z = t;
204 }
205 DUK_ASSERT(y->n >= z->n);
206
207 ny = y->n; nz = z->n;
208 tmp = 0U;
209 for (i = 0; i < ny; i++) {
210 DUK_ASSERT(i < DUK__BI_MAX_PARTS);
211 tmp += y->v[i];
212 if (i < nz) {
213 tmp += z->v[i];
214 }
215 x->v[i] = (duk_uint32_t) (tmp & 0xffffffffUL);
216 tmp = tmp >> 32;
217 }
218 if (tmp != 0U) {
219 DUK_ASSERT(i < DUK__BI_MAX_PARTS);
220 x->v[i++] = (duk_uint32_t) tmp;
221 }
222 x->n = i;
223 DUK_ASSERT(x->n <= DUK__BI_MAX_PARTS);
224
225 /* no need to normalize */
226 DUK_ASSERT(duk__bi_is_valid(x));
227 }
228 #else /* DUK_USE_64BIT_OPS */
duk__bi_add(duk__bigint * x,duk__bigint * y,duk__bigint * z)229 DUK_LOCAL void duk__bi_add(duk__bigint *x, duk__bigint *y, duk__bigint *z) {
230 duk_uint32_t carry, tmp1, tmp2;
231 duk_small_int_t i, ny, nz;
232
233 DUK_ASSERT(duk__bi_is_valid(y));
234 DUK_ASSERT(duk__bi_is_valid(z));
235
236 if (z->n > y->n) {
237 duk__bigint *t;
238 t = y; y = z; z = t;
239 }
240 DUK_ASSERT(y->n >= z->n);
241
242 ny = y->n; nz = z->n;
243 carry = 0U;
244 for (i = 0; i < ny; i++) {
245 /* Carry is detected based on wrapping which relies on exact 32-bit
246 * types.
247 */
248 DUK_ASSERT(i < DUK__BI_MAX_PARTS);
249 tmp1 = y->v[i];
250 tmp2 = tmp1;
251 if (i < nz) {
252 tmp2 += z->v[i];
253 }
254
255 /* Careful with carry condition:
256 * - If carry not added: 0x12345678 + 0 + 0xffffffff = 0x12345677 (< 0x12345678)
257 * - If carry added: 0x12345678 + 1 + 0xffffffff = 0x12345678 (== 0x12345678)
258 */
259 if (carry) {
260 tmp2++;
261 carry = (tmp2 <= tmp1 ? 1U : 0U);
262 } else {
263 carry = (tmp2 < tmp1 ? 1U : 0U);
264 }
265
266 x->v[i] = tmp2;
267 }
268 if (carry) {
269 DUK_ASSERT(i < DUK__BI_MAX_PARTS);
270 DUK_ASSERT(carry == 1U);
271 x->v[i++] = carry;
272 }
273 x->n = i;
274 DUK_ASSERT(x->n <= DUK__BI_MAX_PARTS);
275
276 /* no need to normalize */
277 DUK_ASSERT(duk__bi_is_valid(x));
278 }
279 #endif /* DUK_USE_64BIT_OPS */
280
281 /* x <- y + z */
duk__bi_add_small(duk__bigint * x,duk__bigint * y,duk_uint32_t z)282 DUK_LOCAL void duk__bi_add_small(duk__bigint *x, duk__bigint *y, duk_uint32_t z) {
283 duk__bigint tmp;
284
285 DUK_ASSERT(duk__bi_is_valid(y));
286
287 /* XXX: this could be optimized; there is only one call site now though */
288 duk__bi_set_small(&tmp, z);
289 duk__bi_add(x, y, &tmp);
290
291 DUK_ASSERT(duk__bi_is_valid(x));
292 }
293
294 #if 0 /* unused */
295 /* x <- x + y, use t as temp */
296 DUK_LOCAL void duk__bi_add_copy(duk__bigint *x, duk__bigint *y, duk__bigint *t) {
297 duk__bi_add(t, x, y);
298 duk__bi_copy(x, t);
299 }
300 #endif
301
302 /* x <- y - z, require x >= y => z >= 0, i.e. y >= z */
303 #ifdef DUK_USE_64BIT_OPS
duk__bi_sub(duk__bigint * x,duk__bigint * y,duk__bigint * z)304 DUK_LOCAL void duk__bi_sub(duk__bigint *x, duk__bigint *y, duk__bigint *z) {
305 duk_small_int_t i, ny, nz;
306 duk_uint32_t ty, tz;
307 duk_int64_t tmp;
308
309 DUK_ASSERT(duk__bi_is_valid(y));
310 DUK_ASSERT(duk__bi_is_valid(z));
311 DUK_ASSERT(duk__bi_compare(y, z) >= 0);
312 DUK_ASSERT(y->n >= z->n);
313
314 ny = y->n; nz = z->n;
315 tmp = 0;
316 for (i = 0; i < ny; i++) {
317 ty = y->v[i];
318 if (i < nz) {
319 tz = z->v[i];
320 } else {
321 tz = 0;
322 }
323 tmp = (duk_int64_t) ty - (duk_int64_t) tz + tmp;
324 x->v[i] = (duk_uint32_t) (tmp & 0xffffffffUL);
325 tmp = tmp >> 32; /* 0 or -1 */
326 }
327 DUK_ASSERT(tmp == 0);
328
329 x->n = i;
330 duk__bi_normalize(x); /* need to normalize, may even cancel to 0 */
331 DUK_ASSERT(duk__bi_is_valid(x));
332 }
333 #else
duk__bi_sub(duk__bigint * x,duk__bigint * y,duk__bigint * z)334 DUK_LOCAL void duk__bi_sub(duk__bigint *x, duk__bigint *y, duk__bigint *z) {
335 duk_small_int_t i, ny, nz;
336 duk_uint32_t tmp1, tmp2, borrow;
337
338 DUK_ASSERT(duk__bi_is_valid(y));
339 DUK_ASSERT(duk__bi_is_valid(z));
340 DUK_ASSERT(duk__bi_compare(y, z) >= 0);
341 DUK_ASSERT(y->n >= z->n);
342
343 ny = y->n; nz = z->n;
344 borrow = 0U;
345 for (i = 0; i < ny; i++) {
346 /* Borrow is detected based on wrapping which relies on exact 32-bit
347 * types.
348 */
349 tmp1 = y->v[i];
350 tmp2 = tmp1;
351 if (i < nz) {
352 tmp2 -= z->v[i];
353 }
354
355 /* Careful with borrow condition:
356 * - If borrow not subtracted: 0x12345678 - 0 - 0xffffffff = 0x12345679 (> 0x12345678)
357 * - If borrow subtracted: 0x12345678 - 1 - 0xffffffff = 0x12345678 (== 0x12345678)
358 */
359 if (borrow) {
360 tmp2--;
361 borrow = (tmp2 >= tmp1 ? 1U : 0U);
362 } else {
363 borrow = (tmp2 > tmp1 ? 1U : 0U);
364 }
365
366 x->v[i] = tmp2;
367 }
368 DUK_ASSERT(borrow == 0U);
369
370 x->n = i;
371 duk__bi_normalize(x); /* need to normalize, may even cancel to 0 */
372 DUK_ASSERT(duk__bi_is_valid(x));
373 }
374 #endif
375
376 #if 0 /* unused */
377 /* x <- y - z */
378 DUK_LOCAL void duk__bi_sub_small(duk__bigint *x, duk__bigint *y, duk_uint32_t z) {
379 duk__bigint tmp;
380
381 DUK_ASSERT(duk__bi_is_valid(y));
382
383 /* XXX: this could be optimized */
384 duk__bi_set_small(&tmp, z);
385 duk__bi_sub(x, y, &tmp);
386
387 DUK_ASSERT(duk__bi_is_valid(x));
388 }
389 #endif
390
391 /* x <- x - y, use t as temp */
duk__bi_sub_copy(duk__bigint * x,duk__bigint * y,duk__bigint * t)392 DUK_LOCAL void duk__bi_sub_copy(duk__bigint *x, duk__bigint *y, duk__bigint *t) {
393 duk__bi_sub(t, x, y);
394 duk__bi_copy(x, t);
395 }
396
397 /* x <- y * z */
duk__bi_mul(duk__bigint * x,duk__bigint * y,duk__bigint * z)398 DUK_LOCAL void duk__bi_mul(duk__bigint *x, duk__bigint *y, duk__bigint *z) {
399 duk_small_int_t i, j, nx, nz;
400
401 DUK_ASSERT(duk__bi_is_valid(y));
402 DUK_ASSERT(duk__bi_is_valid(z));
403
404 nx = y->n + z->n; /* max possible */
405 DUK_ASSERT(nx <= DUK__BI_MAX_PARTS);
406
407 if (nx == 0) {
408 /* Both inputs are zero; cases where only one is zero can go
409 * through main algorithm.
410 */
411 x->n = 0;
412 return;
413 }
414
415 DUK_MEMZERO((void *) x->v, (size_t) (sizeof(duk_uint32_t) * nx));
416 x->n = nx;
417
418 nz = z->n;
419 for (i = 0; i < y->n; i++) {
420 #ifdef DUK_USE_64BIT_OPS
421 duk_uint64_t tmp = 0U;
422 for (j = 0; j < nz; j++) {
423 tmp += (duk_uint64_t) y->v[i] * (duk_uint64_t) z->v[j] + x->v[i+j];
424 x->v[i+j] = (duk_uint32_t) (tmp & 0xffffffffUL);
425 tmp = tmp >> 32;
426 }
427 if (tmp > 0) {
428 DUK_ASSERT(i + j < nx);
429 DUK_ASSERT(i + j < DUK__BI_MAX_PARTS);
430 DUK_ASSERT(x->v[i+j] == 0U);
431 x->v[i+j] = (duk_uint32_t) tmp;
432 }
433 #else
434 /*
435 * Multiply + add + carry for 32-bit components using only 16x16->32
436 * multiplies and carry detection based on unsigned overflow.
437 *
438 * 1st mult, 32-bit: (A*2^16 + B)
439 * 2nd mult, 32-bit: (C*2^16 + D)
440 * 3rd add, 32-bit: E
441 * 4th add, 32-bit: F
442 *
443 * (AC*2^16 + B) * (C*2^16 + D) + E + F
444 * = AC*2^32 + AD*2^16 + BC*2^16 + BD + E + F
445 * = AC*2^32 + (AD + BC)*2^16 + (BD + E + F)
446 * = AC*2^32 + AD*2^16 + BC*2^16 + (BD + E + F)
447 */
448 duk_uint32_t a, b, c, d, e, f;
449 duk_uint32_t r, s, t;
450
451 a = y->v[i]; b = a & 0xffffUL; a = a >> 16;
452
453 f = 0;
454 for (j = 0; j < nz; j++) {
455 c = z->v[j]; d = c & 0xffffUL; c = c >> 16;
456 e = x->v[i+j];
457
458 /* build result as: (r << 32) + s: start with (BD + E + F) */
459 r = 0;
460 s = b * d;
461
462 /* add E */
463 t = s + e;
464 if (t < s) { r++; } /* carry */
465 s = t;
466
467 /* add F */
468 t = s + f;
469 if (t < s) { r++; } /* carry */
470 s = t;
471
472 /* add BC*2^16 */
473 t = b * c;
474 r += (t >> 16);
475 t = s + ((t & 0xffffUL) << 16);
476 if (t < s) { r++; } /* carry */
477 s = t;
478
479 /* add AD*2^16 */
480 t = a * d;
481 r += (t >> 16);
482 t = s + ((t & 0xffffUL) << 16);
483 if (t < s) { r++; } /* carry */
484 s = t;
485
486 /* add AC*2^32 */
487 t = a * c;
488 r += t;
489
490 DUK_DDD(DUK_DDDPRINT("ab=%08lx cd=%08lx ef=%08lx -> rs=%08lx %08lx",
491 (unsigned long) y->v[i], (unsigned long) z->v[j],
492 (unsigned long) x->v[i+j], (unsigned long) r,
493 (unsigned long) s));
494
495 x->v[i+j] = s;
496 f = r;
497 }
498 if (f > 0U) {
499 DUK_ASSERT(i + j < nx);
500 DUK_ASSERT(i + j < DUK__BI_MAX_PARTS);
501 DUK_ASSERT(x->v[i+j] == 0U);
502 x->v[i+j] = (duk_uint32_t) f;
503 }
504 #endif /* DUK_USE_64BIT_OPS */
505 }
506
507 duk__bi_normalize(x);
508 DUK_ASSERT(duk__bi_is_valid(x));
509 }
510
511 /* x <- y * z */
duk__bi_mul_small(duk__bigint * x,duk__bigint * y,duk_uint32_t z)512 DUK_LOCAL void duk__bi_mul_small(duk__bigint *x, duk__bigint *y, duk_uint32_t z) {
513 duk__bigint tmp;
514
515 DUK_ASSERT(duk__bi_is_valid(y));
516
517 /* XXX: this could be optimized */
518 duk__bi_set_small(&tmp, z);
519 duk__bi_mul(x, y, &tmp);
520
521 DUK_ASSERT(duk__bi_is_valid(x));
522 }
523
524 /* x <- x * y, use t as temp */
duk__bi_mul_copy(duk__bigint * x,duk__bigint * y,duk__bigint * t)525 DUK_LOCAL void duk__bi_mul_copy(duk__bigint *x, duk__bigint *y, duk__bigint *t) {
526 duk__bi_mul(t, x, y);
527 duk__bi_copy(x, t);
528 }
529
530 /* x <- x * y, use t as temp */
duk__bi_mul_small_copy(duk__bigint * x,duk_uint32_t y,duk__bigint * t)531 DUK_LOCAL void duk__bi_mul_small_copy(duk__bigint *x, duk_uint32_t y, duk__bigint *t) {
532 duk__bi_mul_small(t, x, y);
533 duk__bi_copy(x, t);
534 }
535
duk__bi_is_even(duk__bigint * x)536 DUK_LOCAL int duk__bi_is_even(duk__bigint *x) {
537 DUK_ASSERT(duk__bi_is_valid(x));
538 return (x->n == 0) || ((x->v[0] & 0x01) == 0);
539 }
540
duk__bi_is_zero(duk__bigint * x)541 DUK_LOCAL int duk__bi_is_zero(duk__bigint *x) {
542 DUK_ASSERT(duk__bi_is_valid(x));
543 return (x->n == 0); /* this is the case for normalized numbers */
544 }
545
546 /* Bigint is 2^52. Used to detect normalized IEEE double mantissa values
547 * which are at the lowest edge (next floating point value downwards has
548 * a different exponent). The lowest mantissa has the form:
549 *
550 * 1000........000 (52 zeroes; only "hidden bit" is set)
551 */
duk__bi_is_2to52(duk__bigint * x)552 DUK_LOCAL duk_small_int_t duk__bi_is_2to52(duk__bigint *x) {
553 DUK_ASSERT(duk__bi_is_valid(x));
554 return (duk_small_int_t)
555 (x->n == 2) && (x->v[0] == 0U) && (x->v[1] == (1U << (52-32)));
556 }
557
558 /* x <- (1<<y) */
duk__bi_twoexp(duk__bigint * x,duk_small_int_t y)559 DUK_LOCAL void duk__bi_twoexp(duk__bigint *x, duk_small_int_t y) {
560 duk_small_int_t n, r;
561
562 n = (y / 32) + 1;
563 DUK_ASSERT(n > 0);
564 r = y % 32;
565 DUK_MEMZERO((void *) x->v, sizeof(duk_uint32_t) * n);
566 x->n = n;
567 x->v[n - 1] = (((duk_uint32_t) 1) << r);
568 }
569
570 /* x <- b^y; use t1 and t2 as temps */
duk__bi_exp_small(duk__bigint * x,duk_small_int_t b,duk_small_int_t y,duk__bigint * t1,duk__bigint * t2)571 DUK_LOCAL void duk__bi_exp_small(duk__bigint *x, duk_small_int_t b, duk_small_int_t y, duk__bigint *t1, duk__bigint *t2) {
572 /* Fast path the binary case */
573
574 DUK_ASSERT(x != t1 && x != t2 && t1 != t2); /* distinct bignums, easy mistake to make */
575 DUK_ASSERT(b >= 0);
576 DUK_ASSERT(y >= 0);
577
578 if (b == 2) {
579 duk__bi_twoexp(x, y);
580 return;
581 }
582
583 /* http://en.wikipedia.org/wiki/Exponentiation_by_squaring */
584
585 DUK_DDD(DUK_DDDPRINT("exp_small: b=%ld, y=%ld", (long) b, (long) y));
586
587 duk__bi_set_small(x, 1);
588 duk__bi_set_small(t1, b);
589 for (;;) {
590 /* Loop structure ensures that we don't compute t1^2 unnecessarily
591 * on the final round, as that might create a bignum exceeding the
592 * current DUK__BI_MAX_PARTS limit.
593 */
594 if (y & 0x01) {
595 duk__bi_mul_copy(x, t1, t2);
596 }
597 y = y >> 1;
598 if (y == 0) {
599 break;
600 }
601 duk__bi_mul_copy(t1, t1, t2);
602 }
603
604 DUK__BI_PRINT("exp_small result", x);
605 }
606
607 /*
608 * A Dragon4 number-to-string variant, based on:
609 *
610 * Guy L. Steele Jr., Jon L. White: "How to Print Floating-Point Numbers
611 * Accurately"
612 *
613 * Robert G. Burger, R. Kent Dybvig: "Printing Floating-Point Numbers
614 * Quickly and Accurately"
615 *
616 * The current algorithm is based on Figure 1 of the Burger-Dybvig paper,
617 * i.e. the base implementation without logarithm estimation speedups
618 * (these would increase code footprint considerably). Fixed-format output
619 * does not follow the suggestions in the paper; instead, we generate an
620 * extra digit and round-with-carry.
621 *
622 * The same algorithm is used for number parsing (with b=10 and B=2)
623 * by generating one extra digit and doing rounding manually.
624 *
625 * See doc/number-conversion.rst for limitations.
626 */
627
628 /* Maximum number of digits generated. */
629 #define DUK__MAX_OUTPUT_DIGITS 1040 /* (Number.MAX_VALUE).toString(2).length == 1024, + spare */
630
631 /* Maximum number of characters in formatted value. */
632 #define DUK__MAX_FORMATTED_LENGTH 1040 /* (-Number.MAX_VALUE).toString(2).length == 1025, + spare */
633
634 /* Number and (minimum) size of bigints in the nc_ctx structure. */
635 #define DUK__NUMCONV_CTX_NUM_BIGINTS 7
636 #define DUK__NUMCONV_CTX_BIGINTS_SIZE (sizeof(duk__bigint) * DUK__NUMCONV_CTX_NUM_BIGINTS)
637
638 typedef struct {
639 /* Currently about 7*152 = 1064 bytes. The space for these
640 * duk__bigints is used also as a temporary buffer for generating
641 * the final string. This is a bit awkard; a union would be
642 * more correct.
643 */
644 duk__bigint f, r, s, mp, mm, t1, t2;
645
646 duk_small_int_t is_s2n; /* if 1, doing a string-to-number; else doing a number-to-string */
647 duk_small_int_t is_fixed; /* if 1, doing a fixed format output (not free format) */
648 duk_small_int_t req_digits; /* requested number of output digits; 0 = free-format */
649 duk_small_int_t abs_pos; /* digit position is absolute, not relative */
650 duk_small_int_t e; /* exponent for 'f' */
651 duk_small_int_t b; /* input radix */
652 duk_small_int_t B; /* output radix */
653 duk_small_int_t k; /* see algorithm */
654 duk_small_int_t low_ok; /* see algorithm */
655 duk_small_int_t high_ok; /* see algorithm */
656 duk_small_int_t unequal_gaps; /* m+ != m- (very rarely) */
657
658 /* Buffer used for generated digits, values are in the range [0,B-1]. */
659 duk_uint8_t digits[DUK__MAX_OUTPUT_DIGITS];
660 duk_small_int_t count; /* digit count */
661 } duk__numconv_stringify_ctx;
662
663 /* Note: computes with 'idx' in assertions, so caller beware.
664 * 'idx' is preincremented, i.e. '1' on first call, because it
665 * is more convenient for the caller.
666 */
667 #define DUK__DRAGON4_OUTPUT_PREINC(nc_ctx,preinc_idx,x) do { \
668 DUK_ASSERT((preinc_idx) - 1 >= 0); \
669 DUK_ASSERT((preinc_idx) - 1 < DUK__MAX_OUTPUT_DIGITS); \
670 ((nc_ctx)->digits[(preinc_idx) - 1]) = (duk_uint8_t) (x); \
671 } while (0)
672
duk__dragon4_format_uint32(duk_uint8_t * buf,duk_uint32_t x,duk_small_int_t radix)673 DUK_LOCAL duk_size_t duk__dragon4_format_uint32(duk_uint8_t *buf, duk_uint32_t x, duk_small_int_t radix) {
674 duk_uint8_t *p;
675 duk_size_t len;
676 duk_small_int_t dig;
677 duk_small_int_t t;
678
679 DUK_ASSERT(radix >= 2 && radix <= 36);
680
681 /* A 32-bit unsigned integer formats to at most 32 digits (the
682 * worst case happens with radix == 2). Output the digits backwards,
683 * and use a memmove() to get them in the right place.
684 */
685
686 p = buf + 32;
687 for (;;) {
688 t = x / radix;
689 dig = x - t * radix;
690 x = t;
691
692 DUK_ASSERT(dig >= 0 && dig < 36);
693 *(--p) = DUK__DIGITCHAR(dig);
694
695 if (x == 0) {
696 break;
697 }
698 }
699 len = (duk_size_t) ((buf + 32) - p);
700
701 DUK_MEMMOVE((void *) buf, (const void *) p, (size_t) len);
702
703 return len;
704 }
705
duk__dragon4_prepare(duk__numconv_stringify_ctx * nc_ctx)706 DUK_LOCAL void duk__dragon4_prepare(duk__numconv_stringify_ctx *nc_ctx) {
707 duk_small_int_t lowest_mantissa;
708
709 #if 1
710 /* Assume IEEE round-to-even, so that shorter encoding can be used
711 * when round-to-even would produce correct result. By removing
712 * this check (and having low_ok == high_ok == 0) the results would
713 * still be accurate but in some cases longer than necessary.
714 */
715 if (duk__bi_is_even(&nc_ctx->f)) {
716 DUK_DDD(DUK_DDDPRINT("f is even"));
717 nc_ctx->low_ok = 1;
718 nc_ctx->high_ok = 1;
719 } else {
720 DUK_DDD(DUK_DDDPRINT("f is odd"));
721 nc_ctx->low_ok = 0;
722 nc_ctx->high_ok = 0;
723 }
724 #else
725 /* Note: not honoring round-to-even should work but now generates incorrect
726 * results. For instance, 1e23 serializes to "a000...", i.e. the first digit
727 * equals the radix (10). Scaling stops one step too early in this case.
728 * Don't know why this is the case, but since this code path is unused, it
729 * doesn't matter.
730 */
731 nc_ctx->low_ok = 0;
732 nc_ctx->high_ok = 0;
733 #endif
734
735 /* For string-to-number, pretend we never have the lowest mantissa as there
736 * is no natural "precision" for inputs. Having lowest_mantissa == 0, we'll
737 * fall into the base cases for both e >= 0 and e < 0.
738 */
739 if (nc_ctx->is_s2n) {
740 lowest_mantissa = 0;
741 } else {
742 lowest_mantissa = duk__bi_is_2to52(&nc_ctx->f);
743 }
744
745 nc_ctx->unequal_gaps = 0;
746 if (nc_ctx->e >= 0) {
747 /* exponent non-negative (and thus not minimum exponent) */
748
749 if (lowest_mantissa) {
750 /* (>= e 0) AND (= f (expt b (- p 1)))
751 *
752 * be <- (expt b e) == b^e
753 * be1 <- (* be b) == (expt b (+ e 1)) == b^(e+1)
754 * r <- (* f be1 2) == 2 * f * b^(e+1) [if b==2 -> f * b^(e+2)]
755 * s <- (* b 2) [if b==2 -> 4]
756 * m+ <- be1 == b^(e+1)
757 * m- <- be == b^e
758 * k <- 0
759 * B <- B
760 * low_ok <- round
761 * high_ok <- round
762 */
763
764 DUK_DDD(DUK_DDDPRINT("non-negative exponent (not smallest exponent); "
765 "lowest mantissa value for this exponent -> "
766 "unequal gaps"));
767
768 duk__bi_exp_small(&nc_ctx->mm, nc_ctx->b, nc_ctx->e, &nc_ctx->t1, &nc_ctx->t2); /* mm <- b^e */
769 duk__bi_mul_small(&nc_ctx->mp, &nc_ctx->mm, nc_ctx->b); /* mp <- b^(e+1) */
770 duk__bi_mul_small(&nc_ctx->t1, &nc_ctx->f, 2);
771 duk__bi_mul(&nc_ctx->r, &nc_ctx->t1, &nc_ctx->mp); /* r <- (2 * f) * b^(e+1) */
772 duk__bi_set_small(&nc_ctx->s, nc_ctx->b * 2); /* s <- 2 * b */
773 nc_ctx->unequal_gaps = 1;
774 } else {
775 /* (>= e 0) AND (not (= f (expt b (- p 1))))
776 *
777 * be <- (expt b e) == b^e
778 * r <- (* f be 2) == 2 * f * b^e [if b==2 -> f * b^(e+1)]
779 * s <- 2
780 * m+ <- be == b^e
781 * m- <- be == b^e
782 * k <- 0
783 * B <- B
784 * low_ok <- round
785 * high_ok <- round
786 */
787
788 DUK_DDD(DUK_DDDPRINT("non-negative exponent (not smallest exponent); "
789 "not lowest mantissa for this exponent -> "
790 "equal gaps"));
791
792 duk__bi_exp_small(&nc_ctx->mm, nc_ctx->b, nc_ctx->e, &nc_ctx->t1, &nc_ctx->t2); /* mm <- b^e */
793 duk__bi_copy(&nc_ctx->mp, &nc_ctx->mm); /* mp <- b^e */
794 duk__bi_mul_small(&nc_ctx->t1, &nc_ctx->f, 2);
795 duk__bi_mul(&nc_ctx->r, &nc_ctx->t1, &nc_ctx->mp); /* r <- (2 * f) * b^e */
796 duk__bi_set_small(&nc_ctx->s, 2); /* s <- 2 */
797 }
798 } else {
799 /* When doing string-to-number, lowest_mantissa is always 0 so
800 * the exponent check, while incorrect, won't matter.
801 */
802 if (nc_ctx->e > DUK__IEEE_DOUBLE_EXP_MIN /*not minimum exponent*/ &&
803 lowest_mantissa /* lowest mantissa for this exponent*/) {
804 /* r <- (* f b 2) [if b==2 -> (* f 4)]
805 * s <- (* (expt b (- 1 e)) 2) == b^(1-e) * 2 [if b==2 -> b^(2-e)]
806 * m+ <- b == 2
807 * m- <- 1
808 * k <- 0
809 * B <- B
810 * low_ok <- round
811 * high_ok <- round
812 */
813
814 DUK_DDD(DUK_DDDPRINT("negative exponent; not minimum exponent and "
815 "lowest mantissa for this exponent -> "
816 "unequal gaps"));
817
818 duk__bi_mul_small(&nc_ctx->r, &nc_ctx->f, nc_ctx->b * 2); /* r <- (2 * b) * f */
819 duk__bi_exp_small(&nc_ctx->t1, nc_ctx->b, 1 - nc_ctx->e, &nc_ctx->s, &nc_ctx->t2); /* NB: use 's' as temp on purpose */
820 duk__bi_mul_small(&nc_ctx->s, &nc_ctx->t1, 2); /* s <- b^(1-e) * 2 */
821 duk__bi_set_small(&nc_ctx->mp, 2);
822 duk__bi_set_small(&nc_ctx->mm, 1);
823 nc_ctx->unequal_gaps = 1;
824 } else {
825 /* r <- (* f 2)
826 * s <- (* (expt b (- e)) 2) == b^(-e) * 2 [if b==2 -> b^(1-e)]
827 * m+ <- 1
828 * m- <- 1
829 * k <- 0
830 * B <- B
831 * low_ok <- round
832 * high_ok <- round
833 */
834
835 DUK_DDD(DUK_DDDPRINT("negative exponent; minimum exponent or not "
836 "lowest mantissa for this exponent -> "
837 "equal gaps"));
838
839 duk__bi_mul_small(&nc_ctx->r, &nc_ctx->f, 2); /* r <- 2 * f */
840 duk__bi_exp_small(&nc_ctx->t1, nc_ctx->b, -nc_ctx->e, &nc_ctx->s, &nc_ctx->t2); /* NB: use 's' as temp on purpose */
841 duk__bi_mul_small(&nc_ctx->s, &nc_ctx->t1, 2); /* s <- b^(-e) * 2 */
842 duk__bi_set_small(&nc_ctx->mp, 1);
843 duk__bi_set_small(&nc_ctx->mm, 1);
844 }
845 }
846 }
847
duk__dragon4_scale(duk__numconv_stringify_ctx * nc_ctx)848 DUK_LOCAL void duk__dragon4_scale(duk__numconv_stringify_ctx *nc_ctx) {
849 duk_small_int_t k = 0;
850
851 /* This is essentially the 'scale' algorithm, with recursion removed.
852 * Note that 'k' is either correct immediately, or will move in one
853 * direction in the loop. There's no need to do the low/high checks
854 * on every round (like the Scheme algorithm does).
855 *
856 * The scheme algorithm finds 'k' and updates 's' simultaneously,
857 * while the logical algorithm finds 'k' with 's' having its initial
858 * value, after which 's' is updated separately (see the Burger-Dybvig
859 * paper, Section 3.1, steps 2 and 3).
860 *
861 * The case where m+ == m- (almost always) is optimized for, because
862 * it reduces the bigint operations considerably and almost always
863 * applies. The scale loop only needs to work with m+, so this works.
864 */
865
866 /* XXX: this algorithm could be optimized quite a lot by using e.g.
867 * a logarithm based estimator for 'k' and performing B^n multiplication
868 * using a lookup table or using some bit-representation based exp
869 * algorithm. Currently we just loop, with significant performance
870 * impact for very large and very small numbers.
871 */
872
873 DUK_DDD(DUK_DDDPRINT("scale: B=%ld, low_ok=%ld, high_ok=%ld",
874 (long) nc_ctx->B, (long) nc_ctx->low_ok, (long) nc_ctx->high_ok));
875 DUK__BI_PRINT("r(init)", &nc_ctx->r);
876 DUK__BI_PRINT("s(init)", &nc_ctx->s);
877 DUK__BI_PRINT("mp(init)", &nc_ctx->mp);
878 DUK__BI_PRINT("mm(init)", &nc_ctx->mm);
879
880 for (;;) {
881 DUK_DDD(DUK_DDDPRINT("scale loop (inc k), k=%ld", (long) k));
882 DUK__BI_PRINT("r", &nc_ctx->r);
883 DUK__BI_PRINT("s", &nc_ctx->s);
884 DUK__BI_PRINT("m+", &nc_ctx->mp);
885 DUK__BI_PRINT("m-", &nc_ctx->mm);
886
887 duk__bi_add(&nc_ctx->t1, &nc_ctx->r, &nc_ctx->mp); /* t1 = (+ r m+) */
888 if (duk__bi_compare(&nc_ctx->t1, &nc_ctx->s) >= (nc_ctx->high_ok ? 0 : 1)) {
889 DUK_DDD(DUK_DDDPRINT("k is too low"));
890 /* r <- r
891 * s <- (* s B)
892 * m+ <- m+
893 * m- <- m-
894 * k <- (+ k 1)
895 */
896
897 duk__bi_mul_small_copy(&nc_ctx->s, nc_ctx->B, &nc_ctx->t1);
898 k++;
899 } else {
900 break;
901 }
902 }
903
904 /* k > 0 -> k was too low, and cannot be too high */
905 if (k > 0) {
906 goto skip_dec_k;
907 }
908
909 for (;;) {
910 DUK_DDD(DUK_DDDPRINT("scale loop (dec k), k=%ld", (long) k));
911 DUK__BI_PRINT("r", &nc_ctx->r);
912 DUK__BI_PRINT("s", &nc_ctx->s);
913 DUK__BI_PRINT("m+", &nc_ctx->mp);
914 DUK__BI_PRINT("m-", &nc_ctx->mm);
915
916 duk__bi_add(&nc_ctx->t1, &nc_ctx->r, &nc_ctx->mp); /* t1 = (+ r m+) */
917 duk__bi_mul_small(&nc_ctx->t2, &nc_ctx->t1, nc_ctx->B); /* t2 = (* (+ r m+) B) */
918 if (duk__bi_compare(&nc_ctx->t2, &nc_ctx->s) <= (nc_ctx->high_ok ? -1 : 0)) {
919 DUK_DDD(DUK_DDDPRINT("k is too high"));
920 /* r <- (* r B)
921 * s <- s
922 * m+ <- (* m+ B)
923 * m- <- (* m- B)
924 * k <- (- k 1)
925 */
926 duk__bi_mul_small_copy(&nc_ctx->r, nc_ctx->B, &nc_ctx->t1);
927 duk__bi_mul_small_copy(&nc_ctx->mp, nc_ctx->B, &nc_ctx->t1);
928 if (nc_ctx->unequal_gaps) {
929 DUK_DDD(DUK_DDDPRINT("m+ != m- -> need to update m- too"));
930 duk__bi_mul_small_copy(&nc_ctx->mm, nc_ctx->B, &nc_ctx->t1);
931 }
932 k--;
933 } else {
934 break;
935 }
936 }
937
938 skip_dec_k:
939
940 if (!nc_ctx->unequal_gaps) {
941 DUK_DDD(DUK_DDDPRINT("equal gaps, copy m- from m+"));
942 duk__bi_copy(&nc_ctx->mm, &nc_ctx->mp); /* mm <- mp */
943 }
944 nc_ctx->k = k;
945
946 DUK_DDD(DUK_DDDPRINT("final k: %ld", (long) k));
947 DUK__BI_PRINT("r(final)", &nc_ctx->r);
948 DUK__BI_PRINT("s(final)", &nc_ctx->s);
949 DUK__BI_PRINT("mp(final)", &nc_ctx->mp);
950 DUK__BI_PRINT("mm(final)", &nc_ctx->mm);
951 }
952
duk__dragon4_generate(duk__numconv_stringify_ctx * nc_ctx)953 DUK_LOCAL void duk__dragon4_generate(duk__numconv_stringify_ctx *nc_ctx) {
954 duk_small_int_t tc1, tc2; /* terminating conditions */
955 duk_small_int_t d; /* current digit */
956 duk_small_int_t count = 0; /* digit count */
957
958 /*
959 * Digit generation loop.
960 *
961 * Different termination conditions:
962 *
963 * 1. Free format output. Terminate when shortest accurate
964 * representation found.
965 *
966 * 2. Fixed format output, with specific number of digits.
967 * Ignore termination conditions, terminate when digits
968 * generated. Caller requests an extra digit and rounds.
969 *
970 * 3. Fixed format output, with a specific absolute cut-off
971 * position (e.g. 10 digits after decimal point). Note
972 * that we always generate at least one digit, even if
973 * the digit is below the cut-off point already.
974 */
975
976 for (;;) {
977 DUK_DDD(DUK_DDDPRINT("generate loop, count=%ld, k=%ld, B=%ld, low_ok=%ld, high_ok=%ld",
978 (long) count, (long) nc_ctx->k, (long) nc_ctx->B,
979 (long) nc_ctx->low_ok, (long) nc_ctx->high_ok));
980 DUK__BI_PRINT("r", &nc_ctx->r);
981 DUK__BI_PRINT("s", &nc_ctx->s);
982 DUK__BI_PRINT("m+", &nc_ctx->mp);
983 DUK__BI_PRINT("m-", &nc_ctx->mm);
984
985 /* (quotient-remainder (* r B) s) using a dummy subtraction loop */
986 duk__bi_mul_small(&nc_ctx->t1, &nc_ctx->r, nc_ctx->B); /* t1 <- (* r B) */
987 d = 0;
988 for (;;) {
989 if (duk__bi_compare(&nc_ctx->t1, &nc_ctx->s) < 0) {
990 break;
991 }
992 duk__bi_sub_copy(&nc_ctx->t1, &nc_ctx->s, &nc_ctx->t2); /* t1 <- t1 - s */
993 d++;
994 }
995 duk__bi_copy(&nc_ctx->r, &nc_ctx->t1); /* r <- (remainder (* r B) s) */
996 /* d <- (quotient (* r B) s) (in range 0...B-1) */
997 DUK_DDD(DUK_DDDPRINT("-> d(quot)=%ld", (long) d));
998 DUK__BI_PRINT("r(rem)", &nc_ctx->r);
999
1000 duk__bi_mul_small_copy(&nc_ctx->mp, nc_ctx->B, &nc_ctx->t2); /* m+ <- (* m+ B) */
1001 duk__bi_mul_small_copy(&nc_ctx->mm, nc_ctx->B, &nc_ctx->t2); /* m- <- (* m- B) */
1002 DUK__BI_PRINT("mp(upd)", &nc_ctx->mp);
1003 DUK__BI_PRINT("mm(upd)", &nc_ctx->mm);
1004
1005 /* Terminating conditions. For fixed width output, we just ignore the
1006 * terminating conditions (and pretend that tc1 == tc2 == false). The
1007 * the current shortcut for fixed-format output is to generate a few
1008 * extra digits and use rounding (with carry) to finish the output.
1009 */
1010
1011 if (nc_ctx->is_fixed == 0) {
1012 /* free-form */
1013 tc1 = (duk__bi_compare(&nc_ctx->r, &nc_ctx->mm) <= (nc_ctx->low_ok ? 0 : -1));
1014
1015 duk__bi_add(&nc_ctx->t1, &nc_ctx->r, &nc_ctx->mp); /* t1 <- (+ r m+) */
1016 tc2 = (duk__bi_compare(&nc_ctx->t1, &nc_ctx->s) >= (nc_ctx->high_ok ? 0 : 1));
1017
1018 DUK_DDD(DUK_DDDPRINT("tc1=%ld, tc2=%ld", (long) tc1, (long) tc2));
1019 } else {
1020 /* fixed-format */
1021 tc1 = 0;
1022 tc2 = 0;
1023 }
1024
1025 /* Count is incremented before DUK__DRAGON4_OUTPUT_PREINC() call
1026 * on purpose, which is taken into account by the macro.
1027 */
1028 count++;
1029
1030 if (tc1) {
1031 if (tc2) {
1032 /* tc1 = true, tc2 = true */
1033 duk__bi_mul_small(&nc_ctx->t1, &nc_ctx->r, 2);
1034 if (duk__bi_compare(&nc_ctx->t1, &nc_ctx->s) < 0) { /* (< (* r 2) s) */
1035 DUK_DDD(DUK_DDDPRINT("tc1=true, tc2=true, 2r > s: output d --> %ld (k=%ld)",
1036 (long) d, (long) nc_ctx->k));
1037 DUK__DRAGON4_OUTPUT_PREINC(nc_ctx, count, d);
1038 } else {
1039 DUK_DDD(DUK_DDDPRINT("tc1=true, tc2=true, 2r <= s: output d+1 --> %ld (k=%ld)",
1040 (long) (d + 1), (long) nc_ctx->k));
1041 DUK__DRAGON4_OUTPUT_PREINC(nc_ctx, count, d + 1);
1042 }
1043 break;
1044 } else {
1045 /* tc1 = true, tc2 = false */
1046 DUK_DDD(DUK_DDDPRINT("tc1=true, tc2=false: output d --> %ld (k=%ld)",
1047 (long) d, (long) nc_ctx->k));
1048 DUK__DRAGON4_OUTPUT_PREINC(nc_ctx, count, d);
1049 break;
1050 }
1051 } else {
1052 if (tc2) {
1053 /* tc1 = false, tc2 = true */
1054 DUK_DDD(DUK_DDDPRINT("tc1=false, tc2=true: output d+1 --> %ld (k=%ld)",
1055 (long) (d + 1), (long) nc_ctx->k));
1056 DUK__DRAGON4_OUTPUT_PREINC(nc_ctx, count, d + 1);
1057 break;
1058 } else {
1059 /* tc1 = false, tc2 = false */
1060 DUK_DDD(DUK_DDDPRINT("tc1=false, tc2=false: output d --> %ld (k=%ld)",
1061 (long) d, (long) nc_ctx->k));
1062 DUK__DRAGON4_OUTPUT_PREINC(nc_ctx, count, d);
1063
1064 /* r <- r (updated above: r <- (remainder (* r B) s)
1065 * s <- s
1066 * m+ <- m+ (updated above: m+ <- (* m+ B)
1067 * m- <- m- (updated above: m- <- (* m- B)
1068 * B, low_ok, high_ok are fixed
1069 */
1070
1071 /* fall through and continue for-loop */
1072 }
1073 }
1074
1075 /* fixed-format termination conditions */
1076 if (nc_ctx->is_fixed) {
1077 if (nc_ctx->abs_pos) {
1078 int pos = nc_ctx->k - count + 1; /* count is already incremented, take into account */
1079 DUK_DDD(DUK_DDDPRINT("fixed format, absolute: abs pos=%ld, k=%ld, count=%ld, req=%ld",
1080 (long) pos, (long) nc_ctx->k, (long) count, (long) nc_ctx->req_digits));
1081 if (pos <= nc_ctx->req_digits) {
1082 DUK_DDD(DUK_DDDPRINT("digit position reached req_digits, end generate loop"));
1083 break;
1084 }
1085 } else {
1086 DUK_DDD(DUK_DDDPRINT("fixed format, relative: k=%ld, count=%ld, req=%ld",
1087 (long) nc_ctx->k, (long) count, (long) nc_ctx->req_digits));
1088 if (count >= nc_ctx->req_digits) {
1089 DUK_DDD(DUK_DDDPRINT("digit count reached req_digits, end generate loop"));
1090 break;
1091 }
1092 }
1093 }
1094 } /* for */
1095
1096 nc_ctx->count = count;
1097
1098 DUK_DDD(DUK_DDDPRINT("generate finished"));
1099
1100 #ifdef DUK_USE_DDDPRINT
1101 {
1102 duk_uint8_t buf[2048];
1103 duk_small_int_t i, t;
1104 DUK_MEMZERO(buf, sizeof(buf));
1105 for (i = 0; i < nc_ctx->count; i++) {
1106 t = nc_ctx->digits[i];
1107 if (t < 0 || t > 36) {
1108 buf[i] = (duk_uint8_t) '?';
1109 } else {
1110 buf[i] = (duk_uint8_t) DUK__DIGITCHAR(t);
1111 }
1112 }
1113 DUK_DDD(DUK_DDDPRINT("-> generated digits; k=%ld, digits='%s'",
1114 (long) nc_ctx->k, (const char *) buf));
1115 }
1116 #endif
1117 }
1118
1119 /* Round up digits to a given position. If position is out-of-bounds,
1120 * does nothing. If carry propagates over the first digit, a '1' is
1121 * prepended to digits and 'k' will be updated. Return value indicates
1122 * whether carry propagated over the first digit.
1123 *
1124 * Note that nc_ctx->count is NOT updated based on the rounding position
1125 * (it is updated only if carry overflows over the first digit and an
1126 * extra digit is prepended).
1127 */
duk__dragon4_fixed_format_round(duk__numconv_stringify_ctx * nc_ctx,duk_small_int_t round_idx)1128 DUK_LOCAL duk_small_int_t duk__dragon4_fixed_format_round(duk__numconv_stringify_ctx *nc_ctx, duk_small_int_t round_idx) {
1129 duk_small_int_t t;
1130 duk_uint8_t *p;
1131 duk_uint8_t roundup_limit;
1132 duk_small_int_t ret = 0;
1133
1134 /*
1135 * round_idx points to the digit which is considered for rounding; the
1136 * digit to its left is the final digit of the rounded value. If round_idx
1137 * is zero, rounding will be performed; the result will either be an empty
1138 * rounded value or if carry happens a '1' digit is generated.
1139 */
1140
1141 if (round_idx >= nc_ctx->count) {
1142 DUK_DDD(DUK_DDDPRINT("round_idx out of bounds (%ld >= %ld (count)) -> no rounding",
1143 (long) round_idx, (long) nc_ctx->count));
1144 return 0;
1145 } else if (round_idx < 0) {
1146 DUK_DDD(DUK_DDDPRINT("round_idx out of bounds (%ld < 0) -> no rounding",
1147 (long) round_idx));
1148 return 0;
1149 }
1150
1151 /*
1152 * Round-up limit.
1153 *
1154 * For even values, divides evenly, e.g. 10 -> roundup_limit=5.
1155 *
1156 * For odd values, rounds up, e.g. 3 -> roundup_limit=2.
1157 * If radix is 3, 0/3 -> down, 1/3 -> down, 2/3 -> up.
1158 */
1159 roundup_limit = (duk_uint8_t) ((nc_ctx->B + 1) / 2);
1160
1161 p = &nc_ctx->digits[round_idx];
1162 if (*p >= roundup_limit) {
1163 DUK_DDD(DUK_DDDPRINT("fixed-format rounding carry required"));
1164 /* carry */
1165 for (;;) {
1166 *p = 0;
1167 if (p == &nc_ctx->digits[0]) {
1168 DUK_DDD(DUK_DDDPRINT("carry propagated to first digit -> special case handling"));
1169 DUK_MEMMOVE((void *) (&nc_ctx->digits[1]),
1170 (const void *) (&nc_ctx->digits[0]),
1171 (size_t) (sizeof(char) * nc_ctx->count));
1172 nc_ctx->digits[0] = 1; /* don't increase 'count' */
1173 nc_ctx->k++; /* position of highest digit changed */
1174 nc_ctx->count++; /* number of digits changed */
1175 ret = 1;
1176 break;
1177 }
1178
1179 DUK_DDD(DUK_DDDPRINT("fixed-format rounding carry: B=%ld, roundup_limit=%ld, p=%p, digits=%p",
1180 (long) nc_ctx->B, (long) roundup_limit, (void *) p, (void *) nc_ctx->digits));
1181 p--;
1182 t = *p;
1183 DUK_DDD(DUK_DDDPRINT("digit before carry: %ld", (long) t));
1184 if (++t < nc_ctx->B) {
1185 DUK_DDD(DUK_DDDPRINT("rounding carry terminated"));
1186 *p = (duk_uint8_t) t;
1187 break;
1188 }
1189
1190 DUK_DDD(DUK_DDDPRINT("wraps, carry to next digit"));
1191 }
1192 }
1193
1194 return ret;
1195 }
1196
1197 #define DUK__NO_EXP (65536) /* arbitrary marker, outside valid exp range */
1198
duk__dragon4_convert_and_push(duk__numconv_stringify_ctx * nc_ctx,duk_context * ctx,duk_small_int_t radix,duk_small_int_t digits,duk_small_uint_t flags,duk_small_int_t neg)1199 DUK_LOCAL void duk__dragon4_convert_and_push(duk__numconv_stringify_ctx *nc_ctx,
1200 duk_context *ctx,
1201 duk_small_int_t radix,
1202 duk_small_int_t digits,
1203 duk_small_uint_t flags,
1204 duk_small_int_t neg) {
1205 duk_small_int_t k;
1206 duk_small_int_t pos, pos_end;
1207 duk_small_int_t expt;
1208 duk_small_int_t dig;
1209 duk_uint8_t *q;
1210 duk_uint8_t *buf;
1211
1212 /*
1213 * The string conversion here incorporates all the necessary Ecmascript
1214 * semantics without attempting to be generic. nc_ctx->digits contains
1215 * nc_ctx->count digits (>= 1), with the topmost digit's 'position'
1216 * indicated by nc_ctx->k as follows:
1217 *
1218 * digits="123" count=3 k=0 --> 0.123
1219 * digits="123" count=3 k=1 --> 1.23
1220 * digits="123" count=3 k=5 --> 12300
1221 * digits="123" count=3 k=-1 --> 0.0123
1222 *
1223 * Note that the identifier names used for format selection are different
1224 * in Burger-Dybvig paper and Ecmascript specification (quite confusingly
1225 * so, because e.g. 'k' has a totally different meaning in each). See
1226 * documentation for discussion.
1227 *
1228 * Ecmascript doesn't specify any specific behavior for format selection
1229 * (e.g. when to use exponent notation) for non-base-10 numbers.
1230 *
1231 * The bigint space in the context is reused for string output, as there
1232 * is more than enough space for that (>1kB at the moment), and we avoid
1233 * allocating even more stack.
1234 */
1235
1236 DUK_ASSERT(DUK__NUMCONV_CTX_BIGINTS_SIZE >= DUK__MAX_FORMATTED_LENGTH);
1237 DUK_ASSERT(nc_ctx->count >= 1);
1238
1239 k = nc_ctx->k;
1240 buf = (duk_uint8_t *) &nc_ctx->f; /* XXX: union would be more correct */
1241 q = buf;
1242
1243 /* Exponent handling: if exponent format is used, record exponent value and
1244 * fake k such that one leading digit is generated (e.g. digits=123 -> "1.23").
1245 *
1246 * toFixed() prevents exponent use; otherwise apply a set of criteria to
1247 * match the other API calls (toString(), toPrecision, etc).
1248 */
1249
1250 expt = DUK__NO_EXP;
1251 if (!nc_ctx->abs_pos /* toFixed() */) {
1252 if ((flags & DUK_N2S_FLAG_FORCE_EXP) || /* exponential notation forced */
1253 ((flags & DUK_N2S_FLAG_NO_ZERO_PAD) && /* fixed precision and zero padding would be required */
1254 (k - digits >= 1)) || /* (e.g. k=3, digits=2 -> "12X") */
1255 ((k > 21 || k <= -6) && (radix == 10))) { /* toString() conditions */
1256 DUK_DDD(DUK_DDDPRINT("use exponential notation: k=%ld -> expt=%ld",
1257 (long) k, (long) (k - 1)));
1258 expt = k - 1; /* e.g. 12.3 -> digits="123" k=2 -> 1.23e1 */
1259 k = 1; /* generate mantissa with a single leading whole number digit */
1260 }
1261 }
1262
1263 if (neg) {
1264 *q++ = '-';
1265 }
1266
1267 /* Start position (inclusive) and end position (exclusive) */
1268 pos = (k >= 1 ? k : 1);
1269 if (nc_ctx->is_fixed) {
1270 if (nc_ctx->abs_pos) {
1271 /* toFixed() */
1272 pos_end = -digits;
1273 } else {
1274 pos_end = k - digits;
1275 }
1276 } else {
1277 pos_end = k - nc_ctx->count;
1278 }
1279 if (pos_end > 0) {
1280 pos_end = 0;
1281 }
1282
1283 DUK_DDD(DUK_DDDPRINT("expt=%ld, k=%ld, count=%ld, pos=%ld, pos_end=%ld, is_fixed=%ld, "
1284 "digits=%ld, abs_pos=%ld",
1285 (long) expt, (long) k, (long) nc_ctx->count, (long) pos, (long) pos_end,
1286 (long) nc_ctx->is_fixed, (long) digits, (long) nc_ctx->abs_pos));
1287
1288 /* Digit generation */
1289 while (pos > pos_end) {
1290 DUK_DDD(DUK_DDDPRINT("digit generation: pos=%ld, pos_end=%ld",
1291 (long) pos, (long) pos_end));
1292 if (pos == 0) {
1293 *q++ = (duk_uint8_t) '.';
1294 }
1295 if (pos > k) {
1296 *q++ = (duk_uint8_t) '0';
1297 } else if (pos <= k - nc_ctx->count) {
1298 *q++ = (duk_uint8_t) '0';
1299 } else {
1300 dig = nc_ctx->digits[k - pos];
1301 DUK_ASSERT(dig >= 0 && dig < nc_ctx->B);
1302 *q++ = (duk_uint8_t) DUK__DIGITCHAR(dig);
1303 }
1304
1305 pos--;
1306 }
1307 DUK_ASSERT(pos <= 1);
1308
1309 /* Exponent */
1310 if (expt != DUK__NO_EXP) {
1311 /*
1312 * Exponent notation for non-base-10 numbers isn't specified in Ecmascript
1313 * specification, as it never explicitly turns up: non-decimal numbers can
1314 * only be formatted with Number.prototype.toString([radix]) and for that,
1315 * behavior is not explicitly specified.
1316 *
1317 * Logical choices include formatting the exponent as decimal (e.g. binary
1318 * 100000 as 1e+5) or in current radix (e.g. binary 100000 as 1e+101).
1319 * The Dragon4 algorithm (in the original paper) prints the exponent value
1320 * in the target radix B. However, for radix values 15 and above, the
1321 * exponent separator 'e' is no longer easily parseable. Consider, for
1322 * instance, the number "1.faecee+1c".
1323 */
1324
1325 duk_size_t len;
1326 char expt_sign;
1327
1328 *q++ = 'e';
1329 if (expt >= 0) {
1330 expt_sign = '+';
1331 } else {
1332 expt_sign = '-';
1333 expt = -expt;
1334 }
1335 *q++ = (duk_uint8_t) expt_sign;
1336 len = duk__dragon4_format_uint32(q, (duk_uint32_t) expt, radix);
1337 q += len;
1338 }
1339
1340 duk_push_lstring(ctx, (const char *) buf, (size_t) (q - buf));
1341 }
1342
1343 /*
1344 * Conversion helpers
1345 */
1346
duk__dragon4_double_to_ctx(duk__numconv_stringify_ctx * nc_ctx,duk_double_t x)1347 DUK_LOCAL void duk__dragon4_double_to_ctx(duk__numconv_stringify_ctx *nc_ctx, duk_double_t x) {
1348 duk_double_union u;
1349 duk_uint32_t tmp;
1350 duk_small_int_t expt;
1351
1352 /*
1353 * seeeeeee eeeeffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
1354 * A B C D E F G H
1355 *
1356 * s sign bit
1357 * eee... exponent field
1358 * fff... fraction
1359 *
1360 * ieee value = 1.ffff... * 2^(e - 1023) (normal)
1361 * = 0.ffff... * 2^(-1022) (denormal)
1362 *
1363 * algorithm v = f * b^e
1364 */
1365
1366 DUK_DBLUNION_SET_DOUBLE(&u, x);
1367
1368 nc_ctx->f.n = 2;
1369
1370 tmp = DUK_DBLUNION_GET_LOW32(&u);
1371 nc_ctx->f.v[0] = tmp;
1372 tmp = DUK_DBLUNION_GET_HIGH32(&u);
1373 nc_ctx->f.v[1] = tmp & 0x000fffffUL;
1374 expt = (duk_small_int_t) ((tmp >> 20) & 0x07ffUL);
1375
1376 if (expt == 0) {
1377 /* denormal */
1378 expt = DUK__IEEE_DOUBLE_EXP_MIN - 52;
1379 duk__bi_normalize(&nc_ctx->f);
1380 } else {
1381 /* normal: implicit leading 1-bit */
1382 nc_ctx->f.v[1] |= 0x00100000UL;
1383 expt = expt - DUK__IEEE_DOUBLE_EXP_BIAS - 52;
1384 DUK_ASSERT(duk__bi_is_valid(&nc_ctx->f)); /* true, because v[1] has at least one bit set */
1385 }
1386
1387 DUK_ASSERT(duk__bi_is_valid(&nc_ctx->f));
1388
1389 nc_ctx->e = expt;
1390 }
1391
duk__dragon4_ctx_to_double(duk__numconv_stringify_ctx * nc_ctx,duk_double_t * x)1392 DUK_LOCAL void duk__dragon4_ctx_to_double(duk__numconv_stringify_ctx *nc_ctx, duk_double_t *x) {
1393 duk_double_union u;
1394 duk_small_int_t expt;
1395 duk_small_int_t i;
1396 duk_small_int_t bitstart;
1397 duk_small_int_t bitround;
1398 duk_small_int_t bitidx;
1399 duk_small_int_t skip_round;
1400 duk_uint32_t t, v;
1401
1402 DUK_ASSERT(nc_ctx->count == 53 + 1);
1403
1404 /* Sometimes this assert is not true right now; it will be true after
1405 * rounding. See: test-bug-numconv-mantissa-assert.js.
1406 */
1407 DUK_ASSERT_DISABLE(nc_ctx->digits[0] == 1); /* zero handled by caller */
1408
1409 /* Should not be required because the code below always sets both high
1410 * and low parts, but at least gcc-4.4.5 fails to deduce this correctly
1411 * (perhaps because the low part is set (seemingly) conditionally in a
1412 * loop), so this is here to avoid the bogus warning.
1413 */
1414 DUK_MEMZERO((void *) &u, sizeof(u));
1415
1416 /*
1417 * Figure out how generated digits match up with the mantissa,
1418 * and then perform rounding. If mantissa overflows, need to
1419 * recompute the exponent (it is bumped and may overflow to
1420 * infinity).
1421 *
1422 * For normal numbers the leading '1' is hidden and ignored,
1423 * and the last bit is used for rounding:
1424 *
1425 * rounding pt
1426 * <--------52------->|
1427 * 1 x x x x ... x x x x|y ==> x x x x ... x x x x
1428 *
1429 * For denormals, the leading '1' is included in the number,
1430 * and the rounding point is different:
1431 *
1432 * rounding pt
1433 * <--52 or less--->|
1434 * 1 x x x x ... x x|x x y ==> 0 0 ... 1 x x ... x x
1435 *
1436 * The largest denormals will have a mantissa beginning with
1437 * a '1' (the explicit leading bit); smaller denormals will
1438 * have leading zero bits.
1439 *
1440 * If the exponent would become too high, the result becomes
1441 * Infinity. If the exponent is so small that the entire
1442 * mantissa becomes zero, the result becomes zero.
1443 *
1444 * Note: the Dragon4 'k' is off-by-one with respect to the IEEE
1445 * exponent. For instance, k==0 indicates that the leading '1'
1446 * digit is at the first binary fraction position (0.1xxx...);
1447 * the corresponding IEEE exponent would be -1.
1448 */
1449
1450 skip_round = 0;
1451
1452 recheck_exp:
1453
1454 expt = nc_ctx->k - 1; /* IEEE exp without bias */
1455 if (expt > 1023) {
1456 /* Infinity */
1457 bitstart = -255; /* needed for inf: causes mantissa to become zero,
1458 * and rounding to be skipped.
1459 */
1460 expt = 2047;
1461 } else if (expt >= -1022) {
1462 /* normal */
1463 bitstart = 1; /* skip leading digit */
1464 expt += DUK__IEEE_DOUBLE_EXP_BIAS;
1465 DUK_ASSERT(expt >= 1 && expt <= 2046);
1466 } else {
1467 /* denormal or zero */
1468 bitstart = 1023 + expt; /* expt==-1023 -> bitstart=0 (leading 1);
1469 * expt==-1024 -> bitstart=-1 (one left of leading 1), etc
1470 */
1471 expt = 0;
1472 }
1473 bitround = bitstart + 52;
1474
1475 DUK_DDD(DUK_DDDPRINT("ieee expt=%ld, bitstart=%ld, bitround=%ld",
1476 (long) expt, (long) bitstart, (long) bitround));
1477
1478 if (!skip_round) {
1479 if (duk__dragon4_fixed_format_round(nc_ctx, bitround)) {
1480 /* Corner case: see test-numconv-parse-mant-carry.js. We could
1481 * just bump the exponent and update bitstart, but it's more robust
1482 * to recompute (but avoid rounding twice).
1483 */
1484 DUK_DDD(DUK_DDDPRINT("rounding caused exponent to be bumped, recheck exponent"));
1485 skip_round = 1;
1486 goto recheck_exp;
1487 }
1488 }
1489
1490 /*
1491 * Create mantissa
1492 */
1493
1494 t = 0;
1495 for (i = 0; i < 52; i++) {
1496 bitidx = bitstart + 52 - 1 - i;
1497 if (bitidx >= nc_ctx->count) {
1498 v = 0;
1499 } else if (bitidx < 0) {
1500 v = 0;
1501 } else {
1502 v = nc_ctx->digits[bitidx];
1503 }
1504 DUK_ASSERT(v == 0 || v == 1);
1505 t += v << (i % 32);
1506 if (i == 31) {
1507 /* low 32 bits is complete */
1508 DUK_DBLUNION_SET_LOW32(&u, t);
1509 t = 0;
1510 }
1511 }
1512 /* t has high mantissa */
1513
1514 DUK_DDD(DUK_DDDPRINT("mantissa is complete: %08lx %08lx",
1515 (unsigned long) t,
1516 (unsigned long) DUK_DBLUNION_GET_LOW32(&u)));
1517
1518 DUK_ASSERT(expt >= 0 && expt <= 0x7ffL);
1519 t += expt << 20;
1520 #if 0 /* caller handles sign change */
1521 if (negative) {
1522 t |= 0x80000000U;
1523 }
1524 #endif
1525 DUK_DBLUNION_SET_HIGH32(&u, t);
1526
1527 DUK_DDD(DUK_DDDPRINT("number is complete: %08lx %08lx",
1528 (unsigned long) DUK_DBLUNION_GET_HIGH32(&u),
1529 (unsigned long) DUK_DBLUNION_GET_LOW32(&u)));
1530
1531 *x = DUK_DBLUNION_GET_DOUBLE(&u);
1532 }
1533
1534 /*
1535 * Exposed number-to-string API
1536 *
1537 * Input: [ number ]
1538 * Output: [ string ]
1539 */
1540
duk_numconv_stringify(duk_context * ctx,duk_small_int_t radix,duk_small_int_t digits,duk_small_uint_t flags)1541 DUK_INTERNAL void duk_numconv_stringify(duk_context *ctx, duk_small_int_t radix, duk_small_int_t digits, duk_small_uint_t flags) {
1542 duk_double_t x;
1543 duk_small_int_t c;
1544 duk_small_int_t neg;
1545 duk_uint32_t uval;
1546 duk__numconv_stringify_ctx nc_ctx_alloc; /* large context; around 2kB now */
1547 duk__numconv_stringify_ctx *nc_ctx = &nc_ctx_alloc;
1548
1549 x = (duk_double_t) duk_require_number(ctx, -1);
1550 duk_pop(ctx);
1551
1552 /*
1553 * Handle special cases (NaN, infinity, zero).
1554 */
1555
1556 c = (duk_small_int_t) DUK_FPCLASSIFY(x);
1557 if (DUK_SIGNBIT((double) x)) {
1558 x = -x;
1559 neg = 1;
1560 } else {
1561 neg = 0;
1562 }
1563
1564 /* NaN sign bit is platform specific with unpacked, un-normalized NaNs */
1565 DUK_ASSERT(c == DUK_FP_NAN || DUK_SIGNBIT((double) x) == 0);
1566
1567 if (c == DUK_FP_NAN) {
1568 duk_push_hstring_stridx(ctx, DUK_STRIDX_NAN);
1569 return;
1570 } else if (c == DUK_FP_INFINITE) {
1571 if (neg) {
1572 /* -Infinity */
1573 duk_push_hstring_stridx(ctx, DUK_STRIDX_MINUS_INFINITY);
1574 } else {
1575 /* Infinity */
1576 duk_push_hstring_stridx(ctx, DUK_STRIDX_INFINITY);
1577 }
1578 return;
1579 } else if (c == DUK_FP_ZERO) {
1580 /* We can't shortcut zero here if it goes through special formatting
1581 * (such as forced exponential notation).
1582 */
1583 ;
1584 }
1585
1586 /*
1587 * Handle integers in 32-bit range (that is, [-(2**32-1),2**32-1])
1588 * specially, as they're very likely for embedded programs. This
1589 * is now done for all radix values. We must be careful not to use
1590 * the fast path when special formatting (e.g. forced exponential)
1591 * is in force.
1592 *
1593 * XXX: could save space by supporting radix 10 only and using
1594 * sprintf "%lu" for the fast path and for exponent formatting.
1595 */
1596
1597 uval = (unsigned int) x;
1598 if (((double) uval) == x && /* integer number in range */
1599 flags == 0) { /* no special formatting */
1600 /* use bigint area as a temp */
1601 duk_uint8_t *buf = (duk_uint8_t *) (&nc_ctx->f);
1602 duk_uint8_t *p = buf;
1603
1604 DUK_ASSERT(DUK__NUMCONV_CTX_BIGINTS_SIZE >= 32 + 1); /* max size: radix=2 + sign */
1605 if (neg && uval != 0) {
1606 /* no negative sign for zero */
1607 *p++ = (duk_uint8_t) '-';
1608 }
1609 p += duk__dragon4_format_uint32(p, uval, radix);
1610 duk_push_lstring(ctx, (const char *) buf, (duk_size_t) (p - buf));
1611 return;
1612 }
1613
1614 /*
1615 * Dragon4 setup.
1616 *
1617 * Convert double from IEEE representation for conversion;
1618 * normal finite values have an implicit leading 1-bit. The
1619 * slow path algorithm doesn't handle zero, so zero is special
1620 * cased here but still creates a valid nc_ctx, and goes
1621 * through normal formatting in case special formatting has
1622 * been requested (e.g. forced exponential format: 0 -> "0e+0").
1623 */
1624
1625 /* Would be nice to bulk clear the allocation, but the context
1626 * is 1-2 kilobytes and nothing should rely on it being zeroed.
1627 */
1628 #if 0
1629 DUK_MEMZERO((void *) nc_ctx, sizeof(*nc_ctx)); /* slow init, do only for slow path cases */
1630 #endif
1631
1632 nc_ctx->is_s2n = 0;
1633 nc_ctx->b = 2;
1634 nc_ctx->B = radix;
1635 nc_ctx->abs_pos = 0;
1636 if (flags & DUK_N2S_FLAG_FIXED_FORMAT) {
1637 nc_ctx->is_fixed = 1;
1638 if (flags & DUK_N2S_FLAG_FRACTION_DIGITS) {
1639 /* absolute req_digits; e.g. digits = 1 -> last digit is 0,
1640 * but add an extra digit for rounding.
1641 */
1642 nc_ctx->abs_pos = 1;
1643 nc_ctx->req_digits = (-digits + 1) - 1;
1644 } else {
1645 nc_ctx->req_digits = digits + 1;
1646 }
1647 } else {
1648 nc_ctx->is_fixed = 0;
1649 nc_ctx->req_digits = 0;
1650 }
1651
1652 if (c == DUK_FP_ZERO) {
1653 /* Zero special case: fake requested number of zero digits; ensure
1654 * no sign bit is printed. Relative and absolute fixed format
1655 * require separate handling.
1656 */
1657 duk_small_int_t count;
1658 if (nc_ctx->is_fixed) {
1659 if (nc_ctx->abs_pos) {
1660 count = digits + 2; /* lead zero + 'digits' fractions + 1 for rounding */
1661 } else {
1662 count = digits + 1; /* + 1 for rounding */
1663 }
1664 } else {
1665 count = 1;
1666 }
1667 DUK_DDD(DUK_DDDPRINT("count=%ld", (long) count));
1668 DUK_ASSERT(count >= 1);
1669 DUK_MEMZERO((void *) nc_ctx->digits, count);
1670 nc_ctx->count = count;
1671 nc_ctx->k = 1; /* 0.000... */
1672 neg = 0;
1673 goto zero_skip;
1674 }
1675
1676 duk__dragon4_double_to_ctx(nc_ctx, x); /* -> sets 'f' and 'e' */
1677 DUK__BI_PRINT("f", &nc_ctx->f);
1678 DUK_DDD(DUK_DDDPRINT("e=%ld", (long) nc_ctx->e));
1679
1680 /*
1681 * Dragon4 slow path digit generation.
1682 */
1683
1684 duk__dragon4_prepare(nc_ctx); /* setup many variables in nc_ctx */
1685
1686 DUK_DDD(DUK_DDDPRINT("after prepare:"));
1687 DUK__BI_PRINT("r", &nc_ctx->r);
1688 DUK__BI_PRINT("s", &nc_ctx->s);
1689 DUK__BI_PRINT("mp", &nc_ctx->mp);
1690 DUK__BI_PRINT("mm", &nc_ctx->mm);
1691
1692 duk__dragon4_scale(nc_ctx);
1693
1694 DUK_DDD(DUK_DDDPRINT("after scale; k=%ld", (long) nc_ctx->k));
1695 DUK__BI_PRINT("r", &nc_ctx->r);
1696 DUK__BI_PRINT("s", &nc_ctx->s);
1697 DUK__BI_PRINT("mp", &nc_ctx->mp);
1698 DUK__BI_PRINT("mm", &nc_ctx->mm);
1699
1700 duk__dragon4_generate(nc_ctx);
1701
1702 /*
1703 * Convert and push final string.
1704 */
1705
1706 zero_skip:
1707
1708 if (flags & DUK_N2S_FLAG_FIXED_FORMAT) {
1709 /* Perform fixed-format rounding. */
1710 duk_small_int_t roundpos;
1711 if (flags & DUK_N2S_FLAG_FRACTION_DIGITS) {
1712 /* 'roundpos' is relative to nc_ctx->k and increases to the right
1713 * (opposite of how 'k' changes).
1714 */
1715 roundpos = -digits; /* absolute position for digit considered for rounding */
1716 roundpos = nc_ctx->k - roundpos;
1717 } else {
1718 roundpos = digits;
1719 }
1720 DUK_DDD(DUK_DDDPRINT("rounding: k=%ld, count=%ld, digits=%ld, roundpos=%ld",
1721 (long) nc_ctx->k, (long) nc_ctx->count, (long) digits, (long) roundpos));
1722 (void) duk__dragon4_fixed_format_round(nc_ctx, roundpos);
1723
1724 /* Note: 'count' is currently not adjusted by rounding (i.e. the
1725 * digits are not "chopped off". That shouldn't matter because
1726 * the digit position (absolute or relative) is passed on to the
1727 * convert-and-push function.
1728 */
1729 }
1730
1731 duk__dragon4_convert_and_push(nc_ctx, ctx, radix, digits, flags, neg);
1732 }
1733
1734 /*
1735 * Exposed string-to-number API
1736 *
1737 * Input: [ string ]
1738 * Output: [ number ]
1739 *
1740 * If number parsing fails, a NaN is pushed as the result. If number parsing
1741 * fails due to an internal error, an InternalError is thrown.
1742 */
1743
duk_numconv_parse(duk_context * ctx,duk_small_int_t radix,duk_small_uint_t flags)1744 DUK_INTERNAL void duk_numconv_parse(duk_context *ctx, duk_small_int_t radix, duk_small_uint_t flags) {
1745 duk_hthread *thr = (duk_hthread *) ctx;
1746 duk__numconv_stringify_ctx nc_ctx_alloc; /* large context; around 2kB now */
1747 duk__numconv_stringify_ctx *nc_ctx = &nc_ctx_alloc;
1748 duk_double_t res;
1749 duk_hstring *h_str;
1750 duk_small_int_t expt;
1751 duk_small_int_t expt_neg;
1752 duk_small_int_t expt_adj;
1753 duk_small_int_t neg;
1754 duk_small_int_t dig;
1755 duk_small_int_t dig_whole;
1756 duk_small_int_t dig_lzero;
1757 duk_small_int_t dig_frac;
1758 duk_small_int_t dig_expt;
1759 duk_small_int_t dig_prec;
1760 const duk__exp_limits *explim;
1761 const duk_uint8_t *p;
1762 duk_small_int_t ch;
1763
1764 /* This seems to waste a lot of stack frame entries, but good compilers
1765 * will compute these as needed below. Some of these initial flags are
1766 * also modified in the code below, so they can't all be removed.
1767 */
1768 duk_small_int_t trim_white = (flags & DUK_S2N_FLAG_TRIM_WHITE);
1769 duk_small_int_t allow_expt = (flags & DUK_S2N_FLAG_ALLOW_EXP);
1770 duk_small_int_t allow_garbage = (flags & DUK_S2N_FLAG_ALLOW_GARBAGE);
1771 duk_small_int_t allow_plus = (flags & DUK_S2N_FLAG_ALLOW_PLUS);
1772 duk_small_int_t allow_minus = (flags & DUK_S2N_FLAG_ALLOW_MINUS);
1773 duk_small_int_t allow_infinity = (flags & DUK_S2N_FLAG_ALLOW_INF);
1774 duk_small_int_t allow_frac = (flags & DUK_S2N_FLAG_ALLOW_FRAC);
1775 duk_small_int_t allow_naked_frac = (flags & DUK_S2N_FLAG_ALLOW_NAKED_FRAC);
1776 duk_small_int_t allow_empty_frac = (flags & DUK_S2N_FLAG_ALLOW_EMPTY_FRAC);
1777 duk_small_int_t allow_empty = (flags & DUK_S2N_FLAG_ALLOW_EMPTY_AS_ZERO);
1778 duk_small_int_t allow_leading_zero = (flags & DUK_S2N_FLAG_ALLOW_LEADING_ZERO);
1779 duk_small_int_t allow_auto_hex_int = (flags & DUK_S2N_FLAG_ALLOW_AUTO_HEX_INT);
1780 duk_small_int_t allow_auto_oct_int = (flags & DUK_S2N_FLAG_ALLOW_AUTO_OCT_INT);
1781
1782 DUK_DDD(DUK_DDDPRINT("parse number: %!T, radix=%ld, flags=0x%08lx",
1783 (duk_tval *) duk_get_tval(ctx, -1),
1784 (long) radix, (unsigned long) flags));
1785
1786 DUK_ASSERT(radix >= 2 && radix <= 36);
1787 DUK_ASSERT(radix - 2 < (duk_small_int_t) sizeof(duk__str2num_digits_for_radix));
1788
1789 /*
1790 * Preliminaries: trim, sign, Infinity check
1791 *
1792 * We rely on the interned string having a NUL terminator, which will
1793 * cause a parse failure wherever it is encountered. As a result, we
1794 * don't need separate pointer checks.
1795 *
1796 * There is no special parsing for 'NaN' in the specification although
1797 * 'Infinity' (with an optional sign) is allowed in some contexts.
1798 * Some contexts allow plus/minus sign, while others only allow the
1799 * minus sign (like JSON.parse()).
1800 *
1801 * Automatic hex number detection (leading '0x' or '0X') and octal
1802 * number detection (leading '0' followed by at least one octal digit)
1803 * is done here too.
1804 */
1805
1806 if (trim_white) {
1807 /* Leading / trailing whitespace is sometimes accepted and
1808 * sometimes not. After white space trimming, all valid input
1809 * characters are pure ASCII.
1810 */
1811 duk_trim(ctx, -1);
1812 }
1813 h_str = duk_require_hstring(ctx, -1);
1814 DUK_ASSERT(h_str != NULL);
1815 p = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h_str);
1816
1817 neg = 0;
1818 ch = *p;
1819 if (ch == (duk_small_int_t) '+') {
1820 if (!allow_plus) {
1821 DUK_DDD(DUK_DDDPRINT("parse failed: leading plus sign not allowed"));
1822 goto parse_fail;
1823 }
1824 p++;
1825 } else if (ch == (duk_small_int_t) '-') {
1826 if (!allow_minus) {
1827 DUK_DDD(DUK_DDDPRINT("parse failed: leading minus sign not allowed"));
1828 goto parse_fail;
1829 }
1830 p++;
1831 neg = 1;
1832 }
1833
1834 ch = *p;
1835 if (allow_infinity && ch == (duk_small_int_t) 'I') {
1836 /* Don't check for Infinity unless the context allows it.
1837 * 'Infinity' is a valid integer literal in e.g. base-36:
1838 *
1839 * parseInt('Infinity', 36)
1840 * 1461559270678
1841 */
1842
1843 const duk_uint8_t *q;
1844
1845 /* borrow literal Infinity from builtin string */
1846 q = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(DUK_HTHREAD_STRING_INFINITY(thr));
1847 if (DUK_STRNCMP((const char *) p, (const char *) q, 8) == 0) {
1848 if (!allow_garbage && (p[8] != (duk_uint8_t) 0)) {
1849 DUK_DDD(DUK_DDDPRINT("parse failed: trailing garbage after matching 'Infinity' not allowed"));
1850 goto parse_fail;
1851 } else {
1852 res = DUK_DOUBLE_INFINITY;
1853 goto negcheck_and_ret;
1854 }
1855 }
1856 }
1857 if (ch == (duk_small_int_t) '0') {
1858 duk_small_int_t detect_radix = 0;
1859 ch = p[1];
1860 if (allow_auto_hex_int && (ch == (duk_small_int_t) 'x' || ch == (duk_small_int_t) 'X')) {
1861 DUK_DDD(DUK_DDDPRINT("detected 0x/0X hex prefix, changing radix and preventing fractions and exponent"));
1862 detect_radix = 16;
1863 allow_empty = 0; /* interpret e.g. '0x' and '0xg' as a NaN (= parse error) */
1864 p += 2;
1865 } else if (allow_auto_oct_int && (ch >= (duk_small_int_t) '0' && ch <= (duk_small_int_t) '9')) {
1866 DUK_DDD(DUK_DDDPRINT("detected 0n oct prefix, changing radix and preventing fractions and exponent"));
1867 detect_radix = 8;
1868 allow_empty = 1; /* interpret e.g. '09' as '0', not NaN */
1869 p += 1;
1870 }
1871 if (detect_radix > 0) {
1872 radix = detect_radix;
1873 allow_expt = 0;
1874 allow_frac = 0;
1875 allow_naked_frac = 0;
1876 allow_empty_frac = 0;
1877 allow_leading_zero = 1; /* allow e.g. '0x0009' and '00077' */
1878 }
1879 }
1880
1881 /*
1882 * Scan number and setup for Dragon4.
1883 *
1884 * The fast path case is detected during setup: an integer which
1885 * can be converted without rounding, no net exponent. The fast
1886 * path could be implemented as a separate scan, but may not really
1887 * be worth it: the multiplications for building 'f' are not
1888 * expensive when 'f' is small.
1889 *
1890 * The significand ('f') must contain enough bits of (apparent)
1891 * accuracy, so that Dragon4 will generate enough binary output digits.
1892 * For decimal numbers, this means generating a 20-digit significand,
1893 * which should yield enough practical accuracy to parse IEEE doubles.
1894 * In fact, the Ecmascript specification explicitly allows an
1895 * implementation to treat digits beyond 20 as zeroes (and even
1896 * to round the 20th digit upwards). For non-decimal numbers, the
1897 * appropriate number of digits has been precomputed for comparable
1898 * accuracy.
1899 *
1900 * Digit counts:
1901 *
1902 * [ dig_lzero ]
1903 * |
1904 * .+-..---[ dig_prec ]----.
1905 * | || |
1906 * 0000123.456789012345678901234567890e+123456
1907 * | | | | | |
1908 * `--+--' `------[ dig_frac ]-------' `-+--'
1909 * | |
1910 * [ dig_whole ] [ dig_expt ]
1911 *
1912 * dig_frac and dig_expt are -1 if not present
1913 * dig_lzero is only computed for whole number part
1914 *
1915 * Parsing state
1916 *
1917 * Parsing whole part dig_frac < 0 AND dig_expt < 0
1918 * Parsing fraction part dig_frac >= 0 AND dig_expt < 0
1919 * Parsing exponent part dig_expt >= 0 (dig_frac may be < 0 or >= 0)
1920 *
1921 * Note: in case we hit an implementation limit (like exponent range),
1922 * we should throw an error, NOT return NaN or Infinity. Even with
1923 * very large exponent (or significand) values the final result may be
1924 * finite, so NaN/Infinity would be incorrect.
1925 */
1926
1927 duk__bi_set_small(&nc_ctx->f, 0);
1928 dig_prec = 0;
1929 dig_lzero = 0;
1930 dig_whole = 0;
1931 dig_frac = -1;
1932 dig_expt = -1;
1933 expt = 0;
1934 expt_adj = 0; /* essentially tracks digit position of lowest 'f' digit */
1935 expt_neg = 0;
1936 for (;;) {
1937 ch = *p++;
1938
1939 DUK_DDD(DUK_DDDPRINT("parse digits: p=%p, ch='%c' (%ld), expt=%ld, expt_adj=%ld, "
1940 "dig_whole=%ld, dig_frac=%ld, dig_expt=%ld, dig_lzero=%ld, dig_prec=%ld",
1941 (const void *) p, (int) ((ch >= 0x20 && ch <= 0x7e) ? ch : '?'), (long) ch,
1942 (long) expt, (long) expt_adj, (long) dig_whole, (long) dig_frac,
1943 (long) dig_expt, (long) dig_lzero, (long) dig_prec));
1944 DUK__BI_PRINT("f", &nc_ctx->f);
1945
1946 /* Most common cases first. */
1947 if (ch >= (duk_small_int_t) '0' && ch <= (duk_small_int_t) '9') {
1948 dig = (int) ch - '0' + 0;
1949 } else if (ch == (duk_small_int_t) '.') {
1950 /* A leading digit is not required in some cases, e.g. accept ".123".
1951 * In other cases (JSON.parse()) a leading digit is required. This
1952 * is checked for after the loop.
1953 */
1954 if (dig_frac >= 0 || dig_expt >= 0) {
1955 if (allow_garbage) {
1956 DUK_DDD(DUK_DDDPRINT("garbage termination (invalid period)"));
1957 break;
1958 } else {
1959 DUK_DDD(DUK_DDDPRINT("parse failed: period not allowed"));
1960 goto parse_fail;
1961 }
1962 }
1963
1964 if (!allow_frac) {
1965 /* Some contexts don't allow fractions at all; this can't be a
1966 * post-check because the state ('f' and expt) would be incorrect.
1967 */
1968 if (allow_garbage) {
1969 DUK_DDD(DUK_DDDPRINT("garbage termination (invalid first period)"));
1970 break;
1971 } else {
1972 DUK_DDD(DUK_DDDPRINT("parse failed: fraction part not allowed"));
1973 }
1974 }
1975
1976 DUK_DDD(DUK_DDDPRINT("start fraction part"));
1977 dig_frac = 0;
1978 continue;
1979 } else if (ch == (duk_small_int_t) 0) {
1980 DUK_DDD(DUK_DDDPRINT("NUL termination"));
1981 break;
1982 } else if (allow_expt && dig_expt < 0 && (ch == (duk_small_int_t) 'e' || ch == (duk_small_int_t) 'E')) {
1983 /* Note: we don't parse back exponent notation for anything else
1984 * than radix 10, so this is not an ambiguous check (e.g. hex
1985 * exponent values may have 'e' either as a significand digit
1986 * or as an exponent separator).
1987 *
1988 * If the exponent separator occurs twice, 'e' will be interpreted
1989 * as a digit (= 14) and will be rejected as an invalid decimal
1990 * digit.
1991 */
1992
1993 DUK_DDD(DUK_DDDPRINT("start exponent part"));
1994
1995 /* Exponent without a sign or with a +/- sign is accepted
1996 * by all call sites (even JSON.parse()).
1997 */
1998 ch = *p;
1999 if (ch == (duk_small_int_t) '-') {
2000 expt_neg = 1;
2001 p++;
2002 } else if (ch == (duk_small_int_t) '+') {
2003 p++;
2004 }
2005 dig_expt = 0;
2006 continue;
2007 } else if (ch >= (duk_small_int_t) 'a' && ch <= (duk_small_int_t) 'z') {
2008 dig = (duk_small_int_t) (ch - (duk_small_int_t) 'a' + 0x0a);
2009 } else if (ch >= (duk_small_int_t) 'A' && ch <= (duk_small_int_t) 'Z') {
2010 dig = (duk_small_int_t) (ch - (duk_small_int_t) 'A' + 0x0a);
2011 } else {
2012 dig = 255; /* triggers garbage digit check below */
2013 }
2014 DUK_ASSERT((dig >= 0 && dig <= 35) || dig == 255);
2015
2016 if (dig >= radix) {
2017 if (allow_garbage) {
2018 DUK_DDD(DUK_DDDPRINT("garbage termination"));
2019 break;
2020 } else {
2021 DUK_DDD(DUK_DDDPRINT("parse failed: trailing garbage or invalid digit"));
2022 goto parse_fail;
2023 }
2024 }
2025
2026 if (dig_expt < 0) {
2027 /* whole or fraction digit */
2028
2029 if (dig_prec < duk__str2num_digits_for_radix[radix - 2]) {
2030 /* significant from precision perspective */
2031
2032 duk_small_int_t f_zero = duk__bi_is_zero(&nc_ctx->f);
2033 if (f_zero && dig == 0) {
2034 /* Leading zero is not counted towards precision digits; not
2035 * in the integer part, nor in the fraction part.
2036 */
2037 if (dig_frac < 0) {
2038 dig_lzero++;
2039 }
2040 } else {
2041 /* XXX: join these ops (multiply-accumulate), but only if
2042 * code footprint decreases.
2043 */
2044 duk__bi_mul_small(&nc_ctx->t1, &nc_ctx->f, radix);
2045 duk__bi_add_small(&nc_ctx->f, &nc_ctx->t1, dig);
2046 dig_prec++;
2047 }
2048 } else {
2049 /* Ignore digits beyond a radix-specific limit, but note them
2050 * in expt_adj.
2051 */
2052 expt_adj++;
2053 }
2054
2055 if (dig_frac >= 0) {
2056 dig_frac++;
2057 expt_adj--;
2058 } else {
2059 dig_whole++;
2060 }
2061 } else {
2062 /* exponent digit */
2063
2064 expt = expt * radix + dig;
2065 if (expt > DUK_S2N_MAX_EXPONENT) {
2066 /* impose a reasonable exponent limit, so that exp
2067 * doesn't need to get tracked using a bigint.
2068 */
2069 DUK_DDD(DUK_DDDPRINT("parse failed: exponent too large"));
2070 goto parse_explimit_error;
2071 }
2072 dig_expt++;
2073 }
2074 }
2075
2076 /* Leading zero. */
2077
2078 if (dig_lzero > 0 && dig_whole > 1) {
2079 if (!allow_leading_zero) {
2080 DUK_DDD(DUK_DDDPRINT("parse failed: leading zeroes not allowed in integer part"));
2081 goto parse_fail;
2082 }
2083 }
2084
2085 /* Validity checks for various fraction formats ("0.1", ".1", "1.", "."). */
2086
2087 if (dig_whole == 0) {
2088 if (dig_frac == 0) {
2089 /* "." is not accepted in any format */
2090 DUK_DDD(DUK_DDDPRINT("parse failed: plain period without leading or trailing digits"));
2091 goto parse_fail;
2092 } else if (dig_frac > 0) {
2093 /* ".123" */
2094 if (!allow_naked_frac) {
2095 DUK_DDD(DUK_DDDPRINT("parse failed: fraction part not allowed without "
2096 "leading integer digit(s)"));
2097 goto parse_fail;
2098 }
2099 } else {
2100 /* empty ("") is allowed in some formats (e.g. Number(''), as zero */
2101 if (!allow_empty) {
2102 DUK_DDD(DUK_DDDPRINT("parse failed: empty string not allowed (as zero)"));
2103 goto parse_fail;
2104 }
2105 }
2106 } else {
2107 if (dig_frac == 0) {
2108 /* "123." is allowed in some formats */
2109 if (!allow_empty_frac) {
2110 DUK_DDD(DUK_DDDPRINT("parse failed: empty fractions"));
2111 goto parse_fail;
2112 }
2113 } else if (dig_frac > 0) {
2114 /* "123.456" */
2115 ;
2116 } else {
2117 /* "123" */
2118 ;
2119 }
2120 }
2121
2122 /* Exponent without digits (e.g. "1e" or "1e+"). If trailing garbage is
2123 * allowed, ignore exponent part as garbage (= parse as "1", i.e. exp 0).
2124 */
2125
2126 if (dig_expt == 0) {
2127 if (!allow_garbage) {
2128 DUK_DDD(DUK_DDDPRINT("parse failed: empty exponent"));
2129 goto parse_fail;
2130 }
2131 DUK_ASSERT(expt == 0);
2132 }
2133
2134 if (expt_neg) {
2135 expt = -expt;
2136 }
2137 DUK_DDD(DUK_DDDPRINT("expt=%ld, expt_adj=%ld, net exponent -> %ld",
2138 (long) expt, (long) expt_adj, (long) (expt + expt_adj)));
2139 expt += expt_adj;
2140
2141 /* Fast path check. */
2142
2143 if (nc_ctx->f.n <= 1 && /* 32-bit value */
2144 expt == 0 /* no net exponent */) {
2145 /* Fast path is triggered for no exponent and also for balanced exponent
2146 * and fraction parts, e.g. for "1.23e2" == "123". Remember to respect
2147 * zero sign.
2148 */
2149
2150 /* XXX: could accept numbers larger than 32 bits, e.g. up to 53 bits? */
2151 DUK_DDD(DUK_DDDPRINT("fast path number parse"));
2152 if (nc_ctx->f.n == 1) {
2153 res = (double) nc_ctx->f.v[0];
2154 } else {
2155 res = 0.0;
2156 }
2157 goto negcheck_and_ret;
2158 }
2159
2160 /* Significand ('f') padding. */
2161
2162 while (dig_prec < duk__str2num_digits_for_radix[radix - 2]) {
2163 /* Pad significand with "virtual" zero digits so that Dragon4 will
2164 * have enough (apparent) precision to work with.
2165 */
2166 DUK_DDD(DUK_DDDPRINT("dig_prec=%ld, pad significand with zero", (long) dig_prec));
2167 duk__bi_mul_small_copy(&nc_ctx->f, radix, &nc_ctx->t1);
2168 DUK__BI_PRINT("f", &nc_ctx->f);
2169 expt--;
2170 dig_prec++;
2171 }
2172
2173 DUK_DDD(DUK_DDDPRINT("final exponent: %ld", (long) expt));
2174
2175 /* Detect zero special case. */
2176
2177 if (nc_ctx->f.n == 0) {
2178 /* This may happen even after the fast path check, if exponent is
2179 * not balanced (e.g. "0e1"). Remember to respect zero sign.
2180 */
2181 DUK_DDD(DUK_DDDPRINT("significand is zero"));
2182 res = 0.0;
2183 goto negcheck_and_ret;
2184 }
2185
2186
2187 /* Quick reject of too large or too small exponents. This check
2188 * would be incorrect for zero (e.g. "0e1000" is zero, not Infinity)
2189 * so zero check must be above.
2190 */
2191
2192 explim = &duk__str2num_exp_limits[radix - 2];
2193 if (expt > explim->upper) {
2194 DUK_DDD(DUK_DDDPRINT("exponent too large -> infinite"));
2195 res = (duk_double_t) DUK_DOUBLE_INFINITY;
2196 goto negcheck_and_ret;
2197 } else if (expt < explim->lower) {
2198 DUK_DDD(DUK_DDDPRINT("exponent too small -> zero"));
2199 res = (duk_double_t) 0.0;
2200 goto negcheck_and_ret;
2201 }
2202
2203 nc_ctx->is_s2n = 1;
2204 nc_ctx->e = expt;
2205 nc_ctx->b = radix;
2206 nc_ctx->B = 2;
2207 nc_ctx->is_fixed = 1;
2208 nc_ctx->abs_pos = 0;
2209 nc_ctx->req_digits = 53 + 1;
2210
2211 DUK__BI_PRINT("f", &nc_ctx->f);
2212 DUK_DDD(DUK_DDDPRINT("e=%ld", (long) nc_ctx->e));
2213
2214 /*
2215 * Dragon4 slow path (binary) digit generation.
2216 * An extra digit is generated for rounding.
2217 */
2218
2219 duk__dragon4_prepare(nc_ctx); /* setup many variables in nc_ctx */
2220
2221 DUK_DDD(DUK_DDDPRINT("after prepare:"));
2222 DUK__BI_PRINT("r", &nc_ctx->r);
2223 DUK__BI_PRINT("s", &nc_ctx->s);
2224 DUK__BI_PRINT("mp", &nc_ctx->mp);
2225 DUK__BI_PRINT("mm", &nc_ctx->mm);
2226
2227 duk__dragon4_scale(nc_ctx);
2228
2229 DUK_DDD(DUK_DDDPRINT("after scale; k=%ld", (long) nc_ctx->k));
2230 DUK__BI_PRINT("r", &nc_ctx->r);
2231 DUK__BI_PRINT("s", &nc_ctx->s);
2232 DUK__BI_PRINT("mp", &nc_ctx->mp);
2233 DUK__BI_PRINT("mm", &nc_ctx->mm);
2234
2235 duk__dragon4_generate(nc_ctx);
2236
2237 DUK_ASSERT(nc_ctx->count == 53 + 1);
2238
2239 /*
2240 * Convert binary digits into an IEEE double. Need to handle
2241 * denormals and rounding correctly.
2242 */
2243
2244 duk__dragon4_ctx_to_double(nc_ctx, &res);
2245 goto negcheck_and_ret;
2246
2247 negcheck_and_ret:
2248 if (neg) {
2249 res = -res;
2250 }
2251 duk_pop(ctx);
2252 duk_push_number(ctx, (double) res);
2253 DUK_DDD(DUK_DDDPRINT("result: %!T", (duk_tval *) duk_get_tval(ctx, -1)));
2254 return;
2255
2256 parse_fail:
2257 DUK_DDD(DUK_DDDPRINT("parse failed"));
2258 duk_pop(ctx);
2259 duk_push_nan(ctx);
2260 return;
2261
2262 parse_explimit_error:
2263 DUK_DDD(DUK_DDDPRINT("parse failed, internal error, can't return a value"));
2264 DUK_ERROR_RANGE(thr, "exponent too large");
2265 return;
2266 }
2267