@@ -11261,9 +11261,10 @@ static JSValue js_dtoa(JSContext *ctx,
11261
11261
return JS_NewStringLen(ctx, buf, len);
11262
11262
}
11263
11263
11264
+ /* d is guaranteed to be finite */
11264
11265
static JSValue js_dtoa_radix(JSContext *ctx, double d, int radix)
11265
11266
{
11266
- char buf[2200], *ptr, *ptr2;
11267
+ char buf[2200], *ptr, *ptr2, *ptr3 ;
11267
11268
/* d is finite */
11268
11269
int sign = d < 0;
11269
11270
int digit;
@@ -11272,8 +11273,8 @@ static JSValue js_dtoa_radix(JSContext *ctx, double d, int radix)
11272
11273
d = fabs(d);
11273
11274
d0 = trunc(d);
11274
11275
frac = d - d0;
11275
- ptr = buf + 1100;
11276
- * ptr = '\0';
11276
+ ptr2 = buf + 1100; /* ptr2 points to the end of the string */
11277
+ ptr = ptr2; /* ptr points to the beginning of the string */
11277
11278
if (d0 <= MAX_SAFE_INTEGER) {
11278
11279
int64_t n = n0 = (int64_t)d0;
11279
11280
while (n >= radix) {
@@ -11297,7 +11298,6 @@ static JSValue js_dtoa_radix(JSContext *ctx, double d, int radix)
11297
11298
if (frac != 0) {
11298
11299
double log2_radix = log2(radix);
11299
11300
double prec = 1023 + 51; // handle subnormals
11300
- ptr2 = buf + 1100;
11301
11301
*ptr2++ = '.';
11302
11302
while (frac != 0 && n0 <= MAX_SAFE_INTEGER/2 && prec > 0) {
11303
11303
frac *= radix;
@@ -11307,32 +11307,45 @@ static JSValue js_dtoa_radix(JSContext *ctx, double d, int radix)
11307
11307
n0 = n0 * radix + digit;
11308
11308
prec -= log2_radix;
11309
11309
}
11310
- *ptr2 = '\0';
11311
11310
if (frac * radix >= radix / 2) {
11311
+ /* round up the string representation manually */
11312
11312
char nine = digits36[radix - 1];
11313
- // round to closest
11314
- while (ptr2[-1] == nine)
11315
- *--ptr2 = '\0';
11313
+ while (ptr2[-1] == nine) {
11314
+ /* strip trailing '9' or equivalent digits */
11315
+ ptr2--;
11316
+ }
11316
11317
if (ptr2[-1] == '.') {
11317
- *--ptr2 = '\0';
11318
- while (ptr2[-1] == nine)
11319
- *--ptr2 = '0';
11318
+ /* strip the 'decimal' point */
11319
+ ptr2--;
11320
+ /* increment the integral part */
11321
+ for (ptr3 = ptr2;;) {
11322
+ if (ptr3[-1] != nine) {
11323
+ ptr3[-1] = (ptr3[-1] == '9') ? 'a' : ptr3[-1] + 1;
11324
+ break;
11325
+ }
11326
+ *--ptr3 = '0';
11327
+ if (ptr3 <= ptr) {
11328
+ /* prepend a '1' if number was all nines */
11329
+ *--ptr = '1';
11330
+ break;
11331
+ }
11332
+ }
11333
+ } else {
11334
+ /* increment the last fractional digit */
11335
+ ptr2[-1] = (ptr2[-1] == '9') ? 'a' : ptr2[-1] + 1;
11320
11336
}
11321
- if (ptr2 - 1 == ptr)
11322
- *--ptr = '1';
11323
- else
11324
- ptr2[-1] += 1;
11325
11337
} else {
11338
+ /* strip trailing fractional zeroes */
11326
11339
while (ptr2[-1] == '0')
11327
- *--ptr2 = '\0' ;
11328
- if (ptr2[-1] == '.')
11329
- *-- ptr2 = '\0' ;
11340
+ ptr2-- ;
11341
+ /* strip the 'decimal' point if last */
11342
+ ptr2 -= ( ptr2[-1] == '.') ;
11330
11343
}
11331
11344
}
11332
11345
done:
11333
11346
ptr[-1] = '-';
11334
11347
ptr -= sign;
11335
- return JS_NewString (ctx, ptr);
11348
+ return js_new_string8 (ctx, (uint8_t *)ptr, ptr2 - ptr);
11336
11349
}
11337
11350
11338
11351
JSValue JS_ToStringInternal(JSContext *ctx, JSValue val, BOOL is_ToPropertyKey)
0 commit comments