Coverage Report

Created: 2023-02-22 06:51

/src/hermes/external/dtoa/dtoa.inc
Line
Count
Source (jump to first uncovered line)
1
/* dtoa for IEEE arithmetic (dmg): convert double to ASCII string.
2
 *
3
 * Inspired by "How to Print Floating-Point Numbers Accurately" by
4
 * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 112-126].
5
 *
6
 * Modifications:
7
 *  1. Rather than iterating, we use a simple numeric overestimate
8
 *     to determine k = floor(log10(d)).  We scale relevant
9
 *     quantities using O(log2(k)) rather than O(k) multiplications.
10
 *  2. For some modes > 2 (corresponding to ecvt and fcvt), we don't
11
 *     try to generate digits strictly left to right.  Instead, we
12
 *     compute with fewer bits and propagate the carry if necessary
13
 *     when rounding the final digit up.  This is often faster.
14
 *  3. Under the assumption that input will be rounded nearest,
15
 *     mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22.
16
 *     That is, we allow equality in stopping tests when the
17
 *     round-nearest rule will give the same floating-point value
18
 *     as would satisfaction of the stopping test with strict
19
 *     inequality.
20
 *  4. We remove common factors of powers of 2 from relevant
21
 *     quantities.
22
 *  5. When converting floating-point integers less than 1e16,
23
 *     we use floating-point arithmetic rather than resorting
24
 *     to multiple-precision integers.
25
 *  6. When asked to produce fewer than 15 digits, we first try
26
 *     to get by with floating-point arithmetic; we resort to
27
 *     multiple-precision integer arithmetic only if we cannot
28
 *     guarantee that the floating-point calculation has given
29
 *     the correctly rounded result.  For k requested digits and
30
 *     "uniformly" distributed input, the probability is
31
 *     something like 10^(k-15) that we must resort to the Long
32
 *     calculation.
33
 */
34
35
 char *
36
g_dtoa
37
#ifdef KR_headers
38
  (dalloc, dd, mode, ndigits, decpt, sign, rve)
39
  dtoa_alloc *dalloc; double dd; int mode, ndigits, *decpt, *sign; char **rve;
40
#else
41
  (dtoa_alloc *dalloc, double dd, int mode, int ndigits, int *decpt, int *sign, char **rve)
42
#endif
43
4.04k
{
44
 /* Arguments ndigits, decpt, sign are similar to those
45
  of ecvt and fcvt; trailing zeros are suppressed from
46
  the returned string.  If not null, *rve is set to point
47
  to the end of the return value.  If d is +-Infinity or NaN,
48
  then *decpt is set to 9999.
49
50
  mode:
51
    0 ==> shortest string that yields d when read in
52
      and rounded to nearest.
53
    1 ==> like 0, but with Steele & White stopping rule;
54
      e.g. with IEEE P754 arithmetic , mode 0 gives
55
      1e23 whereas mode 1 gives 9.999999999999999e22.
56
    2 ==> max(1,ndigits) significant digits.  This gives a
57
      return value similar to that of ecvt, except
58
      that trailing zeros are suppressed.
59
    3 ==> through ndigits past the decimal point.  This
60
      gives a return value similar to that from fcvt,
61
      except that trailing zeros are suppressed, and
62
      ndigits can be negative.
63
    4,5 ==> similar to 2 and 3, respectively, but (in
64
      round-nearest mode) with the tests of mode 0 to
65
      possibly return a shorter string that rounds to d.
66
      With IEEE arithmetic and compilation with
67
      -DHonor_FLT_ROUNDS, modes 4 and 5 behave the same
68
      as modes 2 and 3 when FLT_ROUNDS != 1.
69
    6-9 ==> Debugging modes similar to mode - 4:  don't try
70
      fast floating-point estimate (if applicable).
71
72
    Values of mode other than 0-9 are treated as mode 0.
73
74
    Sufficient space is allocated to the return value
75
    to hold the suppressed trailing zeros.
76
  */
77
78
4.04k
  int bbits, b2, b5, be, dig, i, ieps, ilim, ilim0, ilim1,
79
4.04k
    j, j1 = 0, k, k0, k_check, leftright, m2, m5, s2, s5,
80
4.04k
    spec_case, try_quick;
81
4.04k
  Long L;
82
4.04k
#ifndef Sudden_Underflow
83
4.04k
  int denorm;
84
4.04k
  ULong x;
85
4.04k
#endif
86
4.04k
  Bigint *b, *b1, *delta, *mlo, *mhi, *S;
87
4.04k
  U d2, eps, u;
88
4.04k
  double ds;
89
4.04k
  char *s, *s0;
90
4.04k
#ifndef No_leftright
91
4.04k
#ifdef IEEE_Arith
92
4.04k
  U eps1;
93
4.04k
#endif
94
4.04k
#endif
95
#ifdef SET_INEXACT
96
  int inexact, oldinexact;
97
#endif
98
#ifdef Honor_FLT_ROUNDS /*{*/
99
  int Rounding;
100
#ifdef Trust_FLT_ROUNDS /*{{ only define this if FLT_ROUNDS really works! */
101
  Rounding = Flt_Rounds;
102
#else /*}{*/
103
  Rounding = 1;
104
  switch(fegetround()) {
105
    case FE_TOWARDZERO: Rounding = 0; break;
106
    case FE_UPWARD: Rounding = 2; break;
107
    case FE_DOWNWARD: Rounding = 3;
108
    }
109
#endif /*}}*/
110
#endif /*}*/
111
112
#ifndef MULTIPLE_THREADS
113
  if (dtoa_result) {
114
    g_freedtoa(dtoa_result);
115
    dtoa_result = 0;
116
    }
117
#endif
118
119
4.04k
  u.d = dd;
120
4.04k
  if (word0(&u) & Sign_bit) {
121
    /* set sign for everything, including 0's and NaNs */
122
3.97k
    *sign = 1;
123
3.97k
    word0(&u) &= ~Sign_bit; /* clear sign bit */
124
3.97k
    }
125
63
  else
126
63
    *sign = 0;
127
128
4.04k
#if defined(IEEE_Arith) + defined(VAX)
129
4.04k
#ifdef IEEE_Arith
130
4.04k
  if ((word0(&u) & Exp_mask) == Exp_mask)
131
#else
132
  if (word0(&u)  == 0x8000)
133
#endif
134
0
    {
135
    /* Infinity or NaN */
136
0
    *decpt = 9999;
137
0
#ifdef IEEE_Arith
138
0
    if (!word1(&u) && !(word0(&u) & 0xfffff))
139
0
      return nrv_alloc(dalloc, "Infinity", rve, 8);
140
0
#endif
141
0
    return nrv_alloc(dalloc, "NaN", rve, 3);
142
0
    }
143
4.04k
#endif
144
#ifdef IBM
145
  dval(&u) += 0; /* normalize */
146
#endif
147
4.04k
  if (!dval(&u)) {
148
0
    *decpt = 1;
149
0
    return nrv_alloc(dalloc, "0", rve, 1);
150
0
    }
151
152
#ifdef SET_INEXACT
153
  try_quick = oldinexact = get_inexact();
154
  inexact = 1;
155
#endif
156
#ifdef Honor_FLT_ROUNDS
157
  if (Rounding >= 2) {
158
    if (*sign)
159
      Rounding = Rounding == 2 ? 0 : 2;
160
    else
161
      if (Rounding != 2)
162
        Rounding = 0;
163
    }
164
#endif
165
166
4.04k
  b = d2b(dalloc, &u, &be, &bbits);
167
#ifdef Sudden_Underflow
168
  i = (int)(word0(&u) >> Exp_shift1 & (Exp_mask>>Exp_shift1));
169
#else
170
4.04k
  if ((i = (int)(word0(&u) >> Exp_shift1 & (Exp_mask>>Exp_shift1)))) {
171
4.04k
#endif
172
4.04k
    dval(&d2) = dval(&u);
173
4.04k
    word0(&d2) &= Frac_mask1;
174
4.04k
    word0(&d2) |= Exp_11;
175
#ifdef IBM
176
    if (j = 11 - hi0bits(word0(&d2) & Frac_mask))
177
      dval(&d2) /= 1 << j;
178
#endif
179
180
    /* log(x) ~=~ log(1.5) + (x-1.5)/1.5
181
     * log10(x)  =  log(x) / log(10)
182
     *    ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10))
183
     * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2)
184
     *
185
     * This suggests computing an approximation k to log10(d) by
186
     *
187
     * k = (i - Bias)*0.301029995663981
188
     *  + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 );
189
     *
190
     * We want k to be too large rather than too small.
191
     * The error in the first-order Taylor series approximation
192
     * is in our favor, so we just round up the constant enough
193
     * to compensate for any error in the multiplication of
194
     * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077,
195
     * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14,
196
     * adding 1e-13 to the constant term more than suffices.
197
     * Hence we adjust the constant term to 0.1760912590558.
198
     * (We could get a more accurate k by invoking log10,
199
     *  but this is probably not worthwhile.)
200
     */
201
202
4.04k
    i -= Bias;
203
#ifdef IBM
204
    i <<= 2;
205
    i += j;
206
#endif
207
4.04k
#ifndef Sudden_Underflow
208
4.04k
    denorm = 0;
209
4.04k
    }
210
0
  else {
211
    /* d is denormalized */
212
213
0
    i = bbits + be + (Bias + (P-1) - 1);
214
0
    x = i > 32  ? word0(&u) << (64 - i) | word1(&u) >> (i - 32)
215
0
          : word1(&u) << (32 - i);
216
0
    dval(&d2) = x;
217
0
    word0(&d2) -= 31*Exp_msk1; /* adjust exponent */
218
0
    i -= (Bias + (P-1) - 1) + 1;
219
0
    denorm = 1;
220
0
    }
221
4.04k
#endif
222
4.04k
  ds = (dval(&d2)-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981;
223
4.04k
  k = (int)ds;
224
4.04k
  if (ds < 0. && ds != k)
225
0
    k--; /* want k = floor(ds) */
226
4.04k
  k_check = 1;
227
4.04k
  if (k >= 0 && k <= Ten_pmax) {
228
4.02k
    if (dval(&u) < tens[k])
229
0
      k--;
230
4.02k
    k_check = 0;
231
4.02k
    }
232
4.04k
  j = bbits - i - 1;
233
4.04k
  if (j >= 0) {
234
54
    b2 = 0;
235
54
    s2 = j;
236
54
    }
237
3.98k
  else {
238
3.98k
    b2 = -j;
239
3.98k
    s2 = 0;
240
3.98k
    }
241
4.04k
  if (k >= 0) {
242
4.04k
    b5 = 0;
243
4.04k
    s5 = k;
244
4.04k
    s2 += k;
245
4.04k
    }
246
0
  else {
247
0
    b2 -= k;
248
0
    b5 = -k;
249
0
    s5 = 0;
250
0
    }
251
4.04k
  if (mode < 0 || mode > 9)
252
0
    mode = 0;
253
254
4.04k
#ifndef SET_INEXACT
255
#ifdef Check_FLT_ROUNDS
256
  try_quick = Rounding == 1;
257
#else
258
4.04k
  try_quick = 1;
259
4.04k
#endif
260
4.04k
#endif /*SET_INEXACT*/
261
262
4.04k
  if (mode > 5) {
263
0
    mode -= 4;
264
0
    try_quick = 0;
265
0
    }
266
4.04k
  leftright = 1;
267
4.04k
  ilim = ilim1 = -1;  /* Values for cases 0 and 1; done here to */
268
        /* silence erroneous "gcc -Wall" warning. */
269
4.04k
  switch(mode) {
270
4.04k
    case 0:
271
4.04k
    case 1:
272
4.04k
      i = 18;
273
4.04k
      ndigits = 0;
274
4.04k
      break;
275
0
    case 2:
276
0
      leftright = 0;
277
      /* no break */
278
0
    case 4:
279
0
      if (ndigits <= 0)
280
0
        ndigits = 1;
281
0
      ilim = ilim1 = i = ndigits;
282
0
      break;
283
0
    case 3:
284
0
      leftright = 0;
285
      /* no break */
286
0
    case 5:
287
0
      i = ndigits + k + 1;
288
0
      ilim = i;
289
0
      ilim1 = i - 1;
290
0
      if (i <= 0)
291
0
        i = 1;
292
4.04k
    }
293
4.04k
  s = s0 = rv_alloc(dalloc, i);
294
295
#ifdef Honor_FLT_ROUNDS
296
  if (mode > 1 && Rounding != 1)
297
    leftright = 0;
298
#endif
299
300
4.04k
  if (ilim >= 0 && ilim <= Quick_max && try_quick) {
301
302
    /* Try to get by with floating-point arithmetic. */
303
304
0
    i = 0;
305
0
    dval(&d2) = dval(&u);
306
0
    k0 = k;
307
0
    ilim0 = ilim;
308
0
    ieps = 2; /* conservative */
309
0
    if (k > 0) {
310
0
      ds = tens[k&0xf];
311
0
      j = k >> 4;
312
0
      if (j & Bletch) {
313
        /* prevent overflows */
314
0
        j &= Bletch - 1;
315
0
        dval(&u) /= bigtens[n_bigtens-1];
316
0
        ieps++;
317
0
        }
318
0
      for(; j; j >>= 1, i++)
319
0
        if (j & 1) {
320
0
          ieps++;
321
0
          ds *= bigtens[i];
322
0
          }
323
0
      dval(&u) /= ds;
324
0
      }
325
0
    else if ((j1 = -k)) {
326
0
      dval(&u) *= tens[j1 & 0xf];
327
0
      for(j = j1 >> 4; j; j >>= 1, i++)
328
0
        if (j & 1) {
329
0
          ieps++;
330
0
          dval(&u) *= bigtens[i];
331
0
          }
332
0
      }
333
0
    if (k_check && dval(&u) < 1. && ilim > 0) {
334
0
      if (ilim1 <= 0)
335
0
        goto fast_failed;
336
0
      ilim = ilim1;
337
0
      k--;
338
0
      dval(&u) *= 10.;
339
0
      ieps++;
340
0
      }
341
0
    dval(&eps) = ieps*dval(&u) + 7.;
342
0
    word0(&eps) -= (P-1)*Exp_msk1;
343
0
    if (ilim == 0) {
344
0
      S = mhi = 0;
345
0
      dval(&u) -= 5.;
346
0
      if (dval(&u) > dval(&eps))
347
0
        goto one_digit;
348
0
      if (dval(&u) < -dval(&eps))
349
0
        goto no_digits;
350
0
      goto fast_failed;
351
0
      }
352
0
#ifndef No_leftright
353
0
    if (leftright) {
354
      /* Use Steele & White method of only
355
       * generating digits needed.
356
       */
357
0
      dval(&eps) = 0.5/tens[ilim-1] - dval(&eps);
358
0
#ifdef IEEE_Arith
359
0
      if (k0 < 0 && j1 >= 307) {
360
0
        eps1.d = 1.01e256; /* 1.01 allows roundoff in the next few lines */
361
0
        word0(&eps1) -= Exp_msk1 * (Bias+P-1);
362
0
        dval(&eps1) *= tens[j1 & 0xf];
363
0
        for(i = 0, j = (j1-256) >> 4; j; j >>= 1, i++)
364
0
          if (j & 1)
365
0
            dval(&eps1) *= bigtens[i];
366
0
        if (eps.d < eps1.d)
367
0
          eps.d = eps1.d;
368
0
        }
369
0
#endif
370
0
      for(i = 0;;) {
371
0
        L = dval(&u);
372
0
        dval(&u) -= L;
373
0
        *s++ = '0' + (int)L;
374
0
        if (1. - dval(&u) < dval(&eps))
375
0
          goto bump_up;
376
0
        if (dval(&u) < dval(&eps))
377
0
          goto ret1;
378
0
        if (++i >= ilim)
379
0
          break;
380
0
        dval(&eps) *= 10.;
381
0
        dval(&u) *= 10.;
382
0
        }
383
0
      }
384
0
    else {
385
0
#endif
386
      /* Generate ilim digits, then fix them up. */
387
0
      dval(&eps) *= tens[ilim-1];
388
0
      for(i = 1;; i++, dval(&u) *= 10.) {
389
0
        L = (Long)(dval(&u));
390
0
        if (!(dval(&u) -= L))
391
0
          ilim = i;
392
0
        *s++ = '0' + (int)L;
393
0
        if (i == ilim) {
394
0
          if (dval(&u) > 0.5 + dval(&eps))
395
0
            goto bump_up;
396
0
          else if (dval(&u) < 0.5 - dval(&eps)) {
397
0
            while(*--s == '0');
398
0
            s++;
399
0
            goto ret1;
400
0
            }
401
0
          break;
402
0
          }
403
0
        }
404
0
#ifndef No_leftright
405
0
      }
406
0
#endif
407
0
 fast_failed:
408
0
    s = s0;
409
0
    dval(&u) = dval(&d2);
410
0
    k = k0;
411
0
    ilim = ilim0;
412
0
    }
413
414
  /* Do we have a "small" integer? */
415
416
4.04k
  if (be >= 0 && k <= Int_max) {
417
    /* Yes. */
418
87
    ds = tens[k];
419
87
    if (ndigits < 0 && ilim <= 0) {
420
0
      S = mhi = 0;
421
0
      if (ilim < 0 || dval(&u) <= 5*ds)
422
0
        goto no_digits;
423
0
      goto one_digit;
424
0
      }
425
357
    for(i = 1;; i++, dval(&u) *= 10.) {
426
357
      L = (Long)(dval(&u) / ds);
427
357
      dval(&u) -= L*ds;
428
#ifdef Check_FLT_ROUNDS
429
      /* If FLT_ROUNDS == 2, L will usually be high by 1 */
430
      if (dval(&u) < 0) {
431
        L--;
432
        dval(&u) += ds;
433
        }
434
#endif
435
357
      *s++ = '0' + (int)L;
436
357
      if (!dval(&u)) {
437
#ifdef SET_INEXACT
438
        inexact = 0;
439
#endif
440
87
        break;
441
87
        }
442
270
      if (i == ilim) {
443
#ifdef Honor_FLT_ROUNDS
444
        if (mode > 1)
445
        switch(Rounding) {
446
          case 0: goto ret1;
447
          case 2: goto bump_up;
448
          }
449
#endif
450
0
        dval(&u) += dval(&u);
451
#ifdef ROUND_BIASED
452
0
        if (dval(&u) >= ds)
453
#else
454
0
        if (dval(&u) > ds || (dval(&u) == ds && L & 1))
455
0
#endif
456
0
          {
457
0
 bump_up:
458
0
          while(*--s == '9')
459
0
            if (s == s0) {
460
0
              k++;
461
0
              *s = '0';
462
0
              break;
463
0
              }
464
0
          ++*s++;
465
0
          }
466
0
        break;
467
0
        }
468
270
      }
469
87
    goto ret1;
470
87
    }
471
472
3.95k
  m2 = b2;
473
3.95k
  m5 = b5;
474
3.95k
  mhi = mlo = 0;
475
3.95k
  if (leftright) {
476
3.95k
    i =
477
3.95k
#ifndef Sudden_Underflow
478
3.95k
      denorm ? be + (Bias + (P-1) - 1 + 1) :
479
3.95k
#endif
480
#ifdef IBM
481
      1 + 4*P - 3 - bbits + ((bbits + be - 1) & 3);
482
#else
483
3.95k
      1 + P - bbits;
484
3.95k
#endif
485
3.95k
    b2 += i;
486
3.95k
    s2 += i;
487
3.95k
    mhi = i2b(dalloc, 1);
488
3.95k
    }
489
3.95k
  if (m2 > 0 && s2 > 0) {
490
3.95k
    i = m2 < s2 ? m2 : s2;
491
3.95k
    b2 -= i;
492
3.95k
    m2 -= i;
493
3.95k
    s2 -= i;
494
3.95k
    }
495
3.95k
  if (b5 > 0) {
496
0
    if (leftright) {
497
0
      if (m5 > 0) {
498
0
        mhi = pow5mult(dalloc, mhi, m5);
499
0
        b1 = mult(dalloc, mhi, b);
500
0
        Bfree(dalloc, b);
501
0
        b = b1;
502
0
        }
503
0
      if ((j = b5 - m5))
504
0
        b = pow5mult(dalloc, b, j);
505
0
      }
506
0
    else
507
0
      b = pow5mult(dalloc, b, b5);
508
0
    }
509
3.95k
  S = i2b(dalloc, 1);
510
3.95k
  if (s5 > 0)
511
3.95k
    S = pow5mult(dalloc, S, s5);
512
513
  /* Check for special case that d is a normalized power of 2. */
514
515
3.95k
  spec_case = 0;
516
3.95k
  if ((mode < 2 || leftright)
517
#ifdef Honor_FLT_ROUNDS
518
      && Rounding == 1
519
#endif
520
3.95k
        ) {
521
3.95k
    if (!word1(&u) && !(word0(&u) & Bndry_mask)
522
3.95k
#ifndef Sudden_Underflow
523
3.95k
     && word0(&u) & (Exp_mask & ~Exp_msk1)
524
3.95k
#endif
525
3.95k
        ) {
526
      /* The special case */
527
10
      b2 += Log2P;
528
10
      s2 += Log2P;
529
10
      spec_case = 1;
530
10
      }
531
3.95k
    }
532
533
  /* Arrange for convenient computation of quotients:
534
   * shift left if necessary so divisor has 4 leading 0 bits.
535
   *
536
   * Perhaps we should just compute leading 28 bits of S once
537
   * and for all and pass them and a shift to quorem, so it
538
   * can do shifts and ors to compute the numerator for q.
539
   */
540
3.95k
  i = dshift(S, s2);
541
3.95k
  b2 += i;
542
3.95k
  m2 += i;
543
3.95k
  s2 += i;
544
3.95k
  if (b2 > 0)
545
3.95k
    b = lshift(dalloc, b, b2);
546
3.95k
  if (s2 > 0)
547
3.95k
    S = lshift(dalloc, S, s2);
548
3.95k
  if (k_check) {
549
14
    if (cmp(b,S) < 0) {
550
0
      k--;
551
0
      b = multadd(dalloc, b, 10, 0);  /* we botched the k estimate */
552
0
      if (leftright)
553
0
        mhi = multadd(dalloc, mhi, 10, 0);
554
0
      ilim = ilim1;
555
0
      }
556
14
    }
557
3.95k
  if (ilim <= 0 && (mode == 3 || mode == 5)) {
558
#ifndef HERMES_FIXEDPOINT_HACK
559
0
    if (ilim < 0 || cmp(b,S = multadd(dalloc, S,5,0)) <= 0) {
560
#else
561
                /// NOTE: The original line here checks that the cmp result is <= 0.
562
                /// This only works for IEEE-754 unbiased rounding, which would
563
                /// make 0.5 round to 0. However, for fixed-point rounding in
564
                /// ES5.1, we need 0.5 to round to 1. JSC modifies the check the same way.
565
0
    if (ilim < 0 || cmp(b,S = multadd(dalloc, S,5,0)) < 0) {
566
0
#endif
567
      /* no digits, fcvt style */
568
0
 no_digits:
569
0
      k = -1 - ndigits;
570
0
      goto ret;
571
0
      }
572
0
 one_digit:
573
0
    *s++ = '1';
574
0
    k++;
575
0
    goto ret;
576
0
    }
577
3.95k
  if (leftright) {
578
3.95k
    if (m2 > 0)
579
3.95k
      mhi = lshift(dalloc, mhi, m2);
580
581
    /* Compute mlo -- check for special case
582
     * that d is a normalized power of 2.
583
     */
584
585
3.95k
    mlo = mhi;
586
3.95k
    if (spec_case) {
587
10
      mhi = Balloc(dalloc, mhi->k);
588
10
      Bcopy(mhi, mlo);
589
10
      mhi = lshift(dalloc, mhi, Log2P);
590
10
      }
591
592
63.2k
    for(i = 1;;i++) {
593
63.2k
      dig = quorem(b,S) + '0';
594
      /* Do we yet have the shortest decimal string
595
       * that will round to d?
596
       */
597
63.2k
      j = cmp(b, mlo);
598
63.2k
      delta = diff(dalloc, S, mhi);
599
63.2k
      j1 = delta->sign ? 1 : cmp(b, delta);
600
63.2k
      Bfree(dalloc, delta);
601
#ifndef ROUND_BIASED
602
63.2k
      if (j1 == 0 && mode != 1 && !(word1(&u) & 1)
603
#ifdef Honor_FLT_ROUNDS
604
        && Rounding >= 1
605
#endif
606
7
                   ) {
607
7
        if (dig == '9')
608
0
          goto round_9_up;
609
7
        if (j > 0)
610
7
          dig++;
611
#ifdef SET_INEXACT
612
        else if (!b->x[0] && b->wds <= 1)
613
          inexact = 0;
614
#endif
615
7
        *s++ = dig;
616
7
        goto ret;
617
7
        }
618
63.2k
#endif
619
63.2k
      if (j < 0 || (j == 0 && mode != 1
620
#ifndef ROUND_BIASED
621
0
              && !(word1(&u) & 1)
622
#endif
623
59.3k
          )) {
624
3.93k
        if (!b->x[0] && b->wds <= 1) {
625
#ifdef SET_INEXACT
626
          inexact = 0;
627
#endif
628
7
          goto accept_dig;
629
7
          }
630
#ifdef Honor_FLT_ROUNDS
631
        if (mode > 1)
632
         switch(Rounding) {
633
          case 0: goto accept_dig;
634
          case 2: goto keep_dig;
635
          }
636
#endif /*Honor_FLT_ROUNDS*/
637
3.93k
        if (j1 > 0) {
638
8
          b = lshift(dalloc, b, 1);
639
8
          j1 = cmp(b, S);
640
#ifdef ROUND_BIASED
641
0
          if (j1 >= 0 /*)*/
642
#else
643
8
          if ((j1 > 0 || (j1 == 0 && dig & 1))
644
#endif
645
8
          && dig++ == '9')
646
0
            goto round_9_up;
647
8
          }
648
3.93k
 accept_dig:
649
3.93k
        *s++ = dig;
650
3.93k
        goto ret;
651
3.93k
        }
652
59.3k
      if (j1 > 0) {
653
#ifdef Honor_FLT_ROUNDS
654
        if (!Rounding)
655
          goto accept_dig;
656
#endif
657
10
        if (dig == '9') { /* possible if i == 1 */
658
0
 round_9_up:
659
0
          *s++ = '9';
660
0
          goto roundoff;
661
0
          }
662
10
        *s++ = dig + 1;
663
10
        goto ret;
664
10
        }
665
#ifdef Honor_FLT_ROUNDS
666
 keep_dig:
667
#endif
668
59.3k
      *s++ = dig;
669
59.3k
      if (i == ilim)
670
0
        break;
671
59.3k
      b = multadd(dalloc, b, 10, 0);
672
59.3k
      if (mlo == mhi)
673
59.1k
        mlo = mhi = multadd(dalloc, mhi, 10, 0);
674
150
      else {
675
150
        mlo = multadd(dalloc, mlo, 10, 0);
676
150
        mhi = multadd(dalloc, mhi, 10, 0);
677
150
        }
678
59.3k
      }
679
3.95k
    }
680
0
  else
681
0
    for(i = 1;; i++) {
682
0
      *s++ = dig = quorem(b,S) + '0';
683
0
      if (!b->x[0] && b->wds <= 1) {
684
#ifdef SET_INEXACT
685
        inexact = 0;
686
#endif
687
0
        goto ret;
688
0
        }
689
0
      if (i >= ilim)
690
0
        break;
691
0
      b = multadd(dalloc, b, 10, 0);
692
0
      }
693
694
  /* Round off last digit */
695
696
#ifdef Honor_FLT_ROUNDS
697
  switch(Rounding) {
698
    case 0: goto trimzeros;
699
    case 2: goto roundoff;
700
    }
701
#endif
702
0
  b = lshift(dalloc, b, 1);
703
0
  j = cmp(b, S);
704
#ifdef ROUND_BIASED
705
0
  if (j >= 0)
706
#else
707
0
  if (j > 0 || (j == 0 && dig & 1))
708
0
#endif
709
0
    {
710
0
 roundoff:
711
0
    while(*--s == '9')
712
0
      if (s == s0) {
713
0
        k++;
714
0
        *s++ = '1';
715
0
        goto ret;
716
0
        }
717
0
    ++*s++;
718
0
    }
719
0
  else {
720
#ifdef Honor_FLT_ROUNDS
721
 trimzeros:
722
#endif
723
0
    while(*--s == '0');
724
0
    s++;
725
0
    }
726
3.95k
 ret:
727
3.95k
  Bfree(dalloc, S);
728
3.95k
  if (mhi) {
729
3.95k
    if (mlo && mlo != mhi)
730
10
      Bfree(dalloc, mlo);
731
3.95k
    Bfree(dalloc, mhi);
732
3.95k
    }
733
4.04k
 ret1:
734
#ifdef SET_INEXACT
735
  if (inexact) {
736
    if (!oldinexact) {
737
      word0(&u) = Exp_1 + (70 << Exp_shift);
738
      word1(&u) = 0;
739
      dval(&u) += 1.;
740
      }
741
    }
742
  else if (!oldinexact)
743
    clear_inexact();
744
#endif
745
4.04k
  Bfree(dalloc, b);
746
4.04k
  *s = 0;
747
4.04k
  *decpt = k + 1;
748
4.04k
  if (rve)
749
4.04k
    *rve = s;
750
4.04k
  return s0;
751
3.95k
  }
g_dtoa
Line
Count
Source
43
4.04k
{
44
 /* Arguments ndigits, decpt, sign are similar to those
45
  of ecvt and fcvt; trailing zeros are suppressed from
46
  the returned string.  If not null, *rve is set to point
47
  to the end of the return value.  If d is +-Infinity or NaN,
48
  then *decpt is set to 9999.
49
50
  mode:
51
    0 ==> shortest string that yields d when read in
52
      and rounded to nearest.
53
    1 ==> like 0, but with Steele & White stopping rule;
54
      e.g. with IEEE P754 arithmetic , mode 0 gives
55
      1e23 whereas mode 1 gives 9.999999999999999e22.
56
    2 ==> max(1,ndigits) significant digits.  This gives a
57
      return value similar to that of ecvt, except
58
      that trailing zeros are suppressed.
59
    3 ==> through ndigits past the decimal point.  This
60
      gives a return value similar to that from fcvt,
61
      except that trailing zeros are suppressed, and
62
      ndigits can be negative.
63
    4,5 ==> similar to 2 and 3, respectively, but (in
64
      round-nearest mode) with the tests of mode 0 to
65
      possibly return a shorter string that rounds to d.
66
      With IEEE arithmetic and compilation with
67
      -DHonor_FLT_ROUNDS, modes 4 and 5 behave the same
68
      as modes 2 and 3 when FLT_ROUNDS != 1.
69
    6-9 ==> Debugging modes similar to mode - 4:  don't try
70
      fast floating-point estimate (if applicable).
71
72
    Values of mode other than 0-9 are treated as mode 0.
73
74
    Sufficient space is allocated to the return value
75
    to hold the suppressed trailing zeros.
76
  */
77
78
4.04k
  int bbits, b2, b5, be, dig, i, ieps, ilim, ilim0, ilim1,
79
4.04k
    j, j1 = 0, k, k0, k_check, leftright, m2, m5, s2, s5,
80
4.04k
    spec_case, try_quick;
81
4.04k
  Long L;
82
4.04k
#ifndef Sudden_Underflow
83
4.04k
  int denorm;
84
4.04k
  ULong x;
85
4.04k
#endif
86
4.04k
  Bigint *b, *b1, *delta, *mlo, *mhi, *S;
87
4.04k
  U d2, eps, u;
88
4.04k
  double ds;
89
4.04k
  char *s, *s0;
90
4.04k
#ifndef No_leftright
91
4.04k
#ifdef IEEE_Arith
92
4.04k
  U eps1;
93
4.04k
#endif
94
4.04k
#endif
95
#ifdef SET_INEXACT
96
  int inexact, oldinexact;
97
#endif
98
#ifdef Honor_FLT_ROUNDS /*{*/
99
  int Rounding;
100
#ifdef Trust_FLT_ROUNDS /*{{ only define this if FLT_ROUNDS really works! */
101
  Rounding = Flt_Rounds;
102
#else /*}{*/
103
  Rounding = 1;
104
  switch(fegetround()) {
105
    case FE_TOWARDZERO: Rounding = 0; break;
106
    case FE_UPWARD: Rounding = 2; break;
107
    case FE_DOWNWARD: Rounding = 3;
108
    }
109
#endif /*}}*/
110
#endif /*}*/
111
112
#ifndef MULTIPLE_THREADS
113
  if (dtoa_result) {
114
    g_freedtoa(dtoa_result);
115
    dtoa_result = 0;
116
    }
117
#endif
118
119
4.04k
  u.d = dd;
120
4.04k
  if (word0(&u) & Sign_bit) {
121
    /* set sign for everything, including 0's and NaNs */
122
3.97k
    *sign = 1;
123
3.97k
    word0(&u) &= ~Sign_bit; /* clear sign bit */
124
3.97k
    }
125
63
  else
126
63
    *sign = 0;
127
128
4.04k
#if defined(IEEE_Arith) + defined(VAX)
129
4.04k
#ifdef IEEE_Arith
130
4.04k
  if ((word0(&u) & Exp_mask) == Exp_mask)
131
#else
132
  if (word0(&u)  == 0x8000)
133
#endif
134
0
    {
135
    /* Infinity or NaN */
136
0
    *decpt = 9999;
137
0
#ifdef IEEE_Arith
138
0
    if (!word1(&u) && !(word0(&u) & 0xfffff))
139
0
      return nrv_alloc(dalloc, "Infinity", rve, 8);
140
0
#endif
141
0
    return nrv_alloc(dalloc, "NaN", rve, 3);
142
0
    }
143
4.04k
#endif
144
#ifdef IBM
145
  dval(&u) += 0; /* normalize */
146
#endif
147
4.04k
  if (!dval(&u)) {
148
0
    *decpt = 1;
149
0
    return nrv_alloc(dalloc, "0", rve, 1);
150
0
    }
151
152
#ifdef SET_INEXACT
153
  try_quick = oldinexact = get_inexact();
154
  inexact = 1;
155
#endif
156
#ifdef Honor_FLT_ROUNDS
157
  if (Rounding >= 2) {
158
    if (*sign)
159
      Rounding = Rounding == 2 ? 0 : 2;
160
    else
161
      if (Rounding != 2)
162
        Rounding = 0;
163
    }
164
#endif
165
166
4.04k
  b = d2b(dalloc, &u, &be, &bbits);
167
#ifdef Sudden_Underflow
168
  i = (int)(word0(&u) >> Exp_shift1 & (Exp_mask>>Exp_shift1));
169
#else
170
4.04k
  if ((i = (int)(word0(&u) >> Exp_shift1 & (Exp_mask>>Exp_shift1)))) {
171
4.04k
#endif
172
4.04k
    dval(&d2) = dval(&u);
173
4.04k
    word0(&d2) &= Frac_mask1;
174
4.04k
    word0(&d2) |= Exp_11;
175
#ifdef IBM
176
    if (j = 11 - hi0bits(word0(&d2) & Frac_mask))
177
      dval(&d2) /= 1 << j;
178
#endif
179
180
    /* log(x) ~=~ log(1.5) + (x-1.5)/1.5
181
     * log10(x)  =  log(x) / log(10)
182
     *    ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10))
183
     * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2)
184
     *
185
     * This suggests computing an approximation k to log10(d) by
186
     *
187
     * k = (i - Bias)*0.301029995663981
188
     *  + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 );
189
     *
190
     * We want k to be too large rather than too small.
191
     * The error in the first-order Taylor series approximation
192
     * is in our favor, so we just round up the constant enough
193
     * to compensate for any error in the multiplication of
194
     * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077,
195
     * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14,
196
     * adding 1e-13 to the constant term more than suffices.
197
     * Hence we adjust the constant term to 0.1760912590558.
198
     * (We could get a more accurate k by invoking log10,
199
     *  but this is probably not worthwhile.)
200
     */
201
202
4.04k
    i -= Bias;
203
#ifdef IBM
204
    i <<= 2;
205
    i += j;
206
#endif
207
4.04k
#ifndef Sudden_Underflow
208
4.04k
    denorm = 0;
209
4.04k
    }
210
0
  else {
211
    /* d is denormalized */
212
213
0
    i = bbits + be + (Bias + (P-1) - 1);
214
0
    x = i > 32  ? word0(&u) << (64 - i) | word1(&u) >> (i - 32)
215
0
          : word1(&u) << (32 - i);
216
0
    dval(&d2) = x;
217
0
    word0(&d2) -= 31*Exp_msk1; /* adjust exponent */
218
0
    i -= (Bias + (P-1) - 1) + 1;
219
0
    denorm = 1;
220
0
    }
221
4.04k
#endif
222
4.04k
  ds = (dval(&d2)-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981;
223
4.04k
  k = (int)ds;
224
4.04k
  if (ds < 0. && ds != k)
225
0
    k--; /* want k = floor(ds) */
226
4.04k
  k_check = 1;
227
4.04k
  if (k >= 0 && k <= Ten_pmax) {
228
4.02k
    if (dval(&u) < tens[k])
229
0
      k--;
230
4.02k
    k_check = 0;
231
4.02k
    }
232
4.04k
  j = bbits - i - 1;
233
4.04k
  if (j >= 0) {
234
54
    b2 = 0;
235
54
    s2 = j;
236
54
    }
237
3.98k
  else {
238
3.98k
    b2 = -j;
239
3.98k
    s2 = 0;
240
3.98k
    }
241
4.04k
  if (k >= 0) {
242
4.04k
    b5 = 0;
243
4.04k
    s5 = k;
244
4.04k
    s2 += k;
245
4.04k
    }
246
0
  else {
247
0
    b2 -= k;
248
0
    b5 = -k;
249
0
    s5 = 0;
250
0
    }
251
4.04k
  if (mode < 0 || mode > 9)
252
0
    mode = 0;
253
254
4.04k
#ifndef SET_INEXACT
255
#ifdef Check_FLT_ROUNDS
256
  try_quick = Rounding == 1;
257
#else
258
4.04k
  try_quick = 1;
259
4.04k
#endif
260
4.04k
#endif /*SET_INEXACT*/
261
262
4.04k
  if (mode > 5) {
263
0
    mode -= 4;
264
0
    try_quick = 0;
265
0
    }
266
4.04k
  leftright = 1;
267
4.04k
  ilim = ilim1 = -1;  /* Values for cases 0 and 1; done here to */
268
        /* silence erroneous "gcc -Wall" warning. */
269
4.04k
  switch(mode) {
270
4.04k
    case 0:
271
4.04k
    case 1:
272
4.04k
      i = 18;
273
4.04k
      ndigits = 0;
274
4.04k
      break;
275
0
    case 2:
276
0
      leftright = 0;
277
      /* no break */
278
0
    case 4:
279
0
      if (ndigits <= 0)
280
0
        ndigits = 1;
281
0
      ilim = ilim1 = i = ndigits;
282
0
      break;
283
0
    case 3:
284
0
      leftright = 0;
285
      /* no break */
286
0
    case 5:
287
0
      i = ndigits + k + 1;
288
0
      ilim = i;
289
0
      ilim1 = i - 1;
290
0
      if (i <= 0)
291
0
        i = 1;
292
4.04k
    }
293
4.04k
  s = s0 = rv_alloc(dalloc, i);
294
295
#ifdef Honor_FLT_ROUNDS
296
  if (mode > 1 && Rounding != 1)
297
    leftright = 0;
298
#endif
299
300
4.04k
  if (ilim >= 0 && ilim <= Quick_max && try_quick) {
301
302
    /* Try to get by with floating-point arithmetic. */
303
304
0
    i = 0;
305
0
    dval(&d2) = dval(&u);
306
0
    k0 = k;
307
0
    ilim0 = ilim;
308
0
    ieps = 2; /* conservative */
309
0
    if (k > 0) {
310
0
      ds = tens[k&0xf];
311
0
      j = k >> 4;
312
0
      if (j & Bletch) {
313
        /* prevent overflows */
314
0
        j &= Bletch - 1;
315
0
        dval(&u) /= bigtens[n_bigtens-1];
316
0
        ieps++;
317
0
        }
318
0
      for(; j; j >>= 1, i++)
319
0
        if (j & 1) {
320
0
          ieps++;
321
0
          ds *= bigtens[i];
322
0
          }
323
0
      dval(&u) /= ds;
324
0
      }
325
0
    else if ((j1 = -k)) {
326
0
      dval(&u) *= tens[j1 & 0xf];
327
0
      for(j = j1 >> 4; j; j >>= 1, i++)
328
0
        if (j & 1) {
329
0
          ieps++;
330
0
          dval(&u) *= bigtens[i];
331
0
          }
332
0
      }
333
0
    if (k_check && dval(&u) < 1. && ilim > 0) {
334
0
      if (ilim1 <= 0)
335
0
        goto fast_failed;
336
0
      ilim = ilim1;
337
0
      k--;
338
0
      dval(&u) *= 10.;
339
0
      ieps++;
340
0
      }
341
0
    dval(&eps) = ieps*dval(&u) + 7.;
342
0
    word0(&eps) -= (P-1)*Exp_msk1;
343
0
    if (ilim == 0) {
344
0
      S = mhi = 0;
345
0
      dval(&u) -= 5.;
346
0
      if (dval(&u) > dval(&eps))
347
0
        goto one_digit;
348
0
      if (dval(&u) < -dval(&eps))
349
0
        goto no_digits;
350
0
      goto fast_failed;
351
0
      }
352
0
#ifndef No_leftright
353
0
    if (leftright) {
354
      /* Use Steele & White method of only
355
       * generating digits needed.
356
       */
357
0
      dval(&eps) = 0.5/tens[ilim-1] - dval(&eps);
358
0
#ifdef IEEE_Arith
359
0
      if (k0 < 0 && j1 >= 307) {
360
0
        eps1.d = 1.01e256; /* 1.01 allows roundoff in the next few lines */
361
0
        word0(&eps1) -= Exp_msk1 * (Bias+P-1);
362
0
        dval(&eps1) *= tens[j1 & 0xf];
363
0
        for(i = 0, j = (j1-256) >> 4; j; j >>= 1, i++)
364
0
          if (j & 1)
365
0
            dval(&eps1) *= bigtens[i];
366
0
        if (eps.d < eps1.d)
367
0
          eps.d = eps1.d;
368
0
        }
369
0
#endif
370
0
      for(i = 0;;) {
371
0
        L = dval(&u);
372
0
        dval(&u) -= L;
373
0
        *s++ = '0' + (int)L;
374
0
        if (1. - dval(&u) < dval(&eps))
375
0
          goto bump_up;
376
0
        if (dval(&u) < dval(&eps))
377
0
          goto ret1;
378
0
        if (++i >= ilim)
379
0
          break;
380
0
        dval(&eps) *= 10.;
381
0
        dval(&u) *= 10.;
382
0
        }
383
0
      }
384
0
    else {
385
0
#endif
386
      /* Generate ilim digits, then fix them up. */
387
0
      dval(&eps) *= tens[ilim-1];
388
0
      for(i = 1;; i++, dval(&u) *= 10.) {
389
0
        L = (Long)(dval(&u));
390
0
        if (!(dval(&u) -= L))
391
0
          ilim = i;
392
0
        *s++ = '0' + (int)L;
393
0
        if (i == ilim) {
394
0
          if (dval(&u) > 0.5 + dval(&eps))
395
0
            goto bump_up;
396
0
          else if (dval(&u) < 0.5 - dval(&eps)) {
397
0
            while(*--s == '0');
398
0
            s++;
399
0
            goto ret1;
400
0
            }
401
0
          break;
402
0
          }
403
0
        }
404
0
#ifndef No_leftright
405
0
      }
406
0
#endif
407
0
 fast_failed:
408
0
    s = s0;
409
0
    dval(&u) = dval(&d2);
410
0
    k = k0;
411
0
    ilim = ilim0;
412
0
    }
413
414
  /* Do we have a "small" integer? */
415
416
4.04k
  if (be >= 0 && k <= Int_max) {
417
    /* Yes. */
418
87
    ds = tens[k];
419
87
    if (ndigits < 0 && ilim <= 0) {
420
0
      S = mhi = 0;
421
0
      if (ilim < 0 || dval(&u) <= 5*ds)
422
0
        goto no_digits;
423
0
      goto one_digit;
424
0
      }
425
357
    for(i = 1;; i++, dval(&u) *= 10.) {
426
357
      L = (Long)(dval(&u) / ds);
427
357
      dval(&u) -= L*ds;
428
#ifdef Check_FLT_ROUNDS
429
      /* If FLT_ROUNDS == 2, L will usually be high by 1 */
430
      if (dval(&u) < 0) {
431
        L--;
432
        dval(&u) += ds;
433
        }
434
#endif
435
357
      *s++ = '0' + (int)L;
436
357
      if (!dval(&u)) {
437
#ifdef SET_INEXACT
438
        inexact = 0;
439
#endif
440
87
        break;
441
87
        }
442
270
      if (i == ilim) {
443
#ifdef Honor_FLT_ROUNDS
444
        if (mode > 1)
445
        switch(Rounding) {
446
          case 0: goto ret1;
447
          case 2: goto bump_up;
448
          }
449
#endif
450
0
        dval(&u) += dval(&u);
451
#ifdef ROUND_BIASED
452
        if (dval(&u) >= ds)
453
#else
454
0
        if (dval(&u) > ds || (dval(&u) == ds && L & 1))
455
0
#endif
456
0
          {
457
0
 bump_up:
458
0
          while(*--s == '9')
459
0
            if (s == s0) {
460
0
              k++;
461
0
              *s = '0';
462
0
              break;
463
0
              }
464
0
          ++*s++;
465
0
          }
466
0
        break;
467
0
        }
468
270
      }
469
87
    goto ret1;
470
87
    }
471
472
3.95k
  m2 = b2;
473
3.95k
  m5 = b5;
474
3.95k
  mhi = mlo = 0;
475
3.95k
  if (leftright) {
476
3.95k
    i =
477
3.95k
#ifndef Sudden_Underflow
478
3.95k
      denorm ? be + (Bias + (P-1) - 1 + 1) :
479
3.95k
#endif
480
#ifdef IBM
481
      1 + 4*P - 3 - bbits + ((bbits + be - 1) & 3);
482
#else
483
3.95k
      1 + P - bbits;
484
3.95k
#endif
485
3.95k
    b2 += i;
486
3.95k
    s2 += i;
487
3.95k
    mhi = i2b(dalloc, 1);
488
3.95k
    }
489
3.95k
  if (m2 > 0 && s2 > 0) {
490
3.95k
    i = m2 < s2 ? m2 : s2;
491
3.95k
    b2 -= i;
492
3.95k
    m2 -= i;
493
3.95k
    s2 -= i;
494
3.95k
    }
495
3.95k
  if (b5 > 0) {
496
0
    if (leftright) {
497
0
      if (m5 > 0) {
498
0
        mhi = pow5mult(dalloc, mhi, m5);
499
0
        b1 = mult(dalloc, mhi, b);
500
0
        Bfree(dalloc, b);
501
0
        b = b1;
502
0
        }
503
0
      if ((j = b5 - m5))
504
0
        b = pow5mult(dalloc, b, j);
505
0
      }
506
0
    else
507
0
      b = pow5mult(dalloc, b, b5);
508
0
    }
509
3.95k
  S = i2b(dalloc, 1);
510
3.95k
  if (s5 > 0)
511
3.95k
    S = pow5mult(dalloc, S, s5);
512
513
  /* Check for special case that d is a normalized power of 2. */
514
515
3.95k
  spec_case = 0;
516
3.95k
  if ((mode < 2 || leftright)
517
#ifdef Honor_FLT_ROUNDS
518
      && Rounding == 1
519
#endif
520
3.95k
        ) {
521
3.95k
    if (!word1(&u) && !(word0(&u) & Bndry_mask)
522
3.95k
#ifndef Sudden_Underflow
523
3.95k
     && word0(&u) & (Exp_mask & ~Exp_msk1)
524
3.95k
#endif
525
3.95k
        ) {
526
      /* The special case */
527
10
      b2 += Log2P;
528
10
      s2 += Log2P;
529
10
      spec_case = 1;
530
10
      }
531
3.95k
    }
532
533
  /* Arrange for convenient computation of quotients:
534
   * shift left if necessary so divisor has 4 leading 0 bits.
535
   *
536
   * Perhaps we should just compute leading 28 bits of S once
537
   * and for all and pass them and a shift to quorem, so it
538
   * can do shifts and ors to compute the numerator for q.
539
   */
540
3.95k
  i = dshift(S, s2);
541
3.95k
  b2 += i;
542
3.95k
  m2 += i;
543
3.95k
  s2 += i;
544
3.95k
  if (b2 > 0)
545
3.95k
    b = lshift(dalloc, b, b2);
546
3.95k
  if (s2 > 0)
547
3.95k
    S = lshift(dalloc, S, s2);
548
3.95k
  if (k_check) {
549
14
    if (cmp(b,S) < 0) {
550
0
      k--;
551
0
      b = multadd(dalloc, b, 10, 0);  /* we botched the k estimate */
552
0
      if (leftright)
553
0
        mhi = multadd(dalloc, mhi, 10, 0);
554
0
      ilim = ilim1;
555
0
      }
556
14
    }
557
3.95k
  if (ilim <= 0 && (mode == 3 || mode == 5)) {
558
0
#ifndef HERMES_FIXEDPOINT_HACK
559
0
    if (ilim < 0 || cmp(b,S = multadd(dalloc, S,5,0)) <= 0) {
560
#else
561
                /// NOTE: The original line here checks that the cmp result is <= 0.
562
                /// This only works for IEEE-754 unbiased rounding, which would
563
                /// make 0.5 round to 0. However, for fixed-point rounding in
564
                /// ES5.1, we need 0.5 to round to 1. JSC modifies the check the same way.
565
    if (ilim < 0 || cmp(b,S = multadd(dalloc, S,5,0)) < 0) {
566
#endif
567
      /* no digits, fcvt style */
568
0
 no_digits:
569
0
      k = -1 - ndigits;
570
0
      goto ret;
571
0
      }
572
0
 one_digit:
573
0
    *s++ = '1';
574
0
    k++;
575
0
    goto ret;
576
0
    }
577
3.95k
  if (leftright) {
578
3.95k
    if (m2 > 0)
579
3.95k
      mhi = lshift(dalloc, mhi, m2);
580
581
    /* Compute mlo -- check for special case
582
     * that d is a normalized power of 2.
583
     */
584
585
3.95k
    mlo = mhi;
586
3.95k
    if (spec_case) {
587
10
      mhi = Balloc(dalloc, mhi->k);
588
10
      Bcopy(mhi, mlo);
589
10
      mhi = lshift(dalloc, mhi, Log2P);
590
10
      }
591
592
63.2k
    for(i = 1;;i++) {
593
63.2k
      dig = quorem(b,S) + '0';
594
      /* Do we yet have the shortest decimal string
595
       * that will round to d?
596
       */
597
63.2k
      j = cmp(b, mlo);
598
63.2k
      delta = diff(dalloc, S, mhi);
599
63.2k
      j1 = delta->sign ? 1 : cmp(b, delta);
600
63.2k
      Bfree(dalloc, delta);
601
63.2k
#ifndef ROUND_BIASED
602
63.2k
      if (j1 == 0 && mode != 1 && !(word1(&u) & 1)
603
#ifdef Honor_FLT_ROUNDS
604
        && Rounding >= 1
605
#endif
606
63.2k
                   ) {
607
7
        if (dig == '9')
608
0
          goto round_9_up;
609
7
        if (j > 0)
610
7
          dig++;
611
#ifdef SET_INEXACT
612
        else if (!b->x[0] && b->wds <= 1)
613
          inexact = 0;
614
#endif
615
7
        *s++ = dig;
616
7
        goto ret;
617
7
        }
618
63.2k
#endif
619
63.2k
      if (j < 0 || (j == 0 && mode != 1
620
59.3k
#ifndef ROUND_BIASED
621
59.3k
              && !(word1(&u) & 1)
622
59.3k
#endif
623
59.3k
          )) {
624
3.93k
        if (!b->x[0] && b->wds <= 1) {
625
#ifdef SET_INEXACT
626
          inexact = 0;
627
#endif
628
7
          goto accept_dig;
629
7
          }
630
#ifdef Honor_FLT_ROUNDS
631
        if (mode > 1)
632
         switch(Rounding) {
633
          case 0: goto accept_dig;
634
          case 2: goto keep_dig;
635
          }
636
#endif /*Honor_FLT_ROUNDS*/
637
3.93k
        if (j1 > 0) {
638
8
          b = lshift(dalloc, b, 1);
639
8
          j1 = cmp(b, S);
640
#ifdef ROUND_BIASED
641
          if (j1 >= 0 /*)*/
642
#else
643
8
          if ((j1 > 0 || (j1 == 0 && dig & 1))
644
8
#endif
645
8
          && dig++ == '9')
646
0
            goto round_9_up;
647
8
          }
648
3.93k
 accept_dig:
649
3.93k
        *s++ = dig;
650
3.93k
        goto ret;
651
3.93k
        }
652
59.3k
      if (j1 > 0) {
653
#ifdef Honor_FLT_ROUNDS
654
        if (!Rounding)
655
          goto accept_dig;
656
#endif
657
10
        if (dig == '9') { /* possible if i == 1 */
658
0
 round_9_up:
659
0
          *s++ = '9';
660
0
          goto roundoff;
661
0
          }
662
10
        *s++ = dig + 1;
663
10
        goto ret;
664
10
        }
665
#ifdef Honor_FLT_ROUNDS
666
 keep_dig:
667
#endif
668
59.3k
      *s++ = dig;
669
59.3k
      if (i == ilim)
670
0
        break;
671
59.3k
      b = multadd(dalloc, b, 10, 0);
672
59.3k
      if (mlo == mhi)
673
59.1k
        mlo = mhi = multadd(dalloc, mhi, 10, 0);
674
150
      else {
675
150
        mlo = multadd(dalloc, mlo, 10, 0);
676
150
        mhi = multadd(dalloc, mhi, 10, 0);
677
150
        }
678
59.3k
      }
679
3.95k
    }
680
0
  else
681
0
    for(i = 1;; i++) {
682
0
      *s++ = dig = quorem(b,S) + '0';
683
0
      if (!b->x[0] && b->wds <= 1) {
684
#ifdef SET_INEXACT
685
        inexact = 0;
686
#endif
687
0
        goto ret;
688
0
        }
689
0
      if (i >= ilim)
690
0
        break;
691
0
      b = multadd(dalloc, b, 10, 0);
692
0
      }
693
694
  /* Round off last digit */
695
696
#ifdef Honor_FLT_ROUNDS
697
  switch(Rounding) {
698
    case 0: goto trimzeros;
699
    case 2: goto roundoff;
700
    }
701
#endif
702
0
  b = lshift(dalloc, b, 1);
703
0
  j = cmp(b, S);
704
#ifdef ROUND_BIASED
705
  if (j >= 0)
706
#else
707
0
  if (j > 0 || (j == 0 && dig & 1))
708
0
#endif
709
0
    {
710
0
 roundoff:
711
0
    while(*--s == '9')
712
0
      if (s == s0) {
713
0
        k++;
714
0
        *s++ = '1';
715
0
        goto ret;
716
0
        }
717
0
    ++*s++;
718
0
    }
719
0
  else {
720
#ifdef Honor_FLT_ROUNDS
721
 trimzeros:
722
#endif
723
0
    while(*--s == '0');
724
0
    s++;
725
0
    }
726
3.95k
 ret:
727
3.95k
  Bfree(dalloc, S);
728
3.95k
  if (mhi) {
729
3.95k
    if (mlo && mlo != mhi)
730
10
      Bfree(dalloc, mlo);
731
3.95k
    Bfree(dalloc, mhi);
732
3.95k
    }
733
4.04k
 ret1:
734
#ifdef SET_INEXACT
735
  if (inexact) {
736
    if (!oldinexact) {
737
      word0(&u) = Exp_1 + (70 << Exp_shift);
738
      word1(&u) = 0;
739
      dval(&u) += 1.;
740
      }
741
    }
742
  else if (!oldinexact)
743
    clear_inexact();
744
#endif
745
4.04k
  Bfree(dalloc, b);
746
4.04k
  *s = 0;
747
4.04k
  *decpt = k + 1;
748
4.04k
  if (rve)
749
4.04k
    *rve = s;
750
4.04k
  return s0;
751
3.95k
  }
Unexecuted instantiation: dtoa_fixedpoint