/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 | } 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 |