2003/05/12 05:10:30
[org.ibex.core.git] / src / org / mozilla / javascript / DToA.java
1 /* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-\r
2  *\r
3  * The contents of this file are subject to the Netscape Public\r
4  * License Version 1.1 (the "License"); you may not use this file\r
5  * except in compliance with the License. You may obtain a copy of\r
6  * the License at http://www.mozilla.org/NPL/\r
7  *\r
8  * Software distributed under the License is distributed on an "AS\r
9  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr\r
10  * implied. See the License for the specific language governing\r
11  * rights and limitations under the License.\r
12  *\r
13  * The Original Code is Rhino code, released\r
14  * May 6, 1999.\r
15  *\r
16  * The Initial Developer of the Original Code is Netscape\r
17  * Communications Corporation.  Portions created by Netscape are\r
18  * Copyright (C) 1997-1999 Netscape Communications Corporation. All\r
19  * Rights Reserved.\r
20  *\r
21  * Contributor(s):\r
22  * Waldemar Horwat\r
23  * Roger Lawrence\r
24  *\r
25  * Alternatively, the contents of this file may be used under the\r
26  * terms of the GNU Public License (the "GPL"), in which case the\r
27  * provisions of the GPL are applicable instead of those above.\r
28  * If you wish to allow use of your version of this file only\r
29  * under the terms of the GPL and not to allow others to use your\r
30  * version of this file under the NPL, indicate your decision by\r
31  * deleting the provisions above and replace them with the notice\r
32  * and other provisions required by the GPL.  If you do not delete\r
33  * the provisions above, a recipient may use your version of this\r
34  * file under either the NPL or the GPL.\r
35  */\r
36 \r
37 package org.mozilla.javascript;\r
38 \r
39 import java.math.BigInteger;\r
40 \r
41 class DToA {\r
42 \r
43 \r
44 /* "-0.0000...(1073 zeros after decimal point)...0001\0" is the longest string that we could produce,\r
45  * which occurs when printing -5e-324 in binary.  We could compute a better estimate of the size of\r
46  * the output string and malloc fewer bytes depending on d and base, but why bother? */\r
47 \r
48     static final int DTOBASESTR_BUFFER_SIZE = 1078;\r
49 \r
50     static char BASEDIGIT(int digit) {\r
51         return (char)((digit >= 10) ? 'a' - 10 + digit : '0' + digit);\r
52     }\r
53         \r
54     static final int\r
55                 DTOSTR_STANDARD = 0,              /* Either fixed or exponential format; round-trip */\r
56                 DTOSTR_STANDARD_EXPONENTIAL = 1,  /* Always exponential format; round-trip */\r
57                 DTOSTR_FIXED = 2,                 /* Round to <precision> digits after the decimal point; exponential if number is large */\r
58                 DTOSTR_EXPONENTIAL = 3,           /* Always exponential format; <precision> significant digits */\r
59                 DTOSTR_PRECISION = 4;             /* Either fixed or exponential format; <precision> significant digits */\r
60         \r
61 \r
62     static final int Frac_mask = 0xfffff;\r
63     static final int Exp_shift = 20;\r
64     static final int Exp_msk1 = 0x100000;\r
65     static final int Bias = 1023;\r
66     static final int P = 53;\r
67 \r
68     static final int Exp_shift1 = 20;\r
69     static final int Exp_mask  = 0x7ff00000;\r
70     static final int Bndry_mask  = 0xfffff;\r
71     static final int Log2P = 1;\r
72 \r
73     static final int Sign_bit = 0x80000000;\r
74     static final int Exp_11  = 0x3ff00000;\r
75         static final int Ten_pmax = 22;\r
76         static final int Quick_max = 14;\r
77         static final int Bletch = 0x10;\r
78         static final int Frac_mask1 = 0xfffff;\r
79         static final int Int_max = 14;\r
80         static final int n_bigtens = 5;\r
81 \r
82         \r
83         static final double tens[] = {\r
84             1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,\r
85             1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,\r
86             1e20, 1e21, 1e22\r
87         };\r
88         \r
89         static final double bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 };\r
90 \r
91     static int lo0bits(int y)\r
92     {\r
93         int k;\r
94         int x = y;\r
95 \r
96         if ((x & 7) != 0) {\r
97             if ((x & 1) != 0)\r
98                 return 0;\r
99             if ((x & 2) != 0) {\r
100                 return 1;\r
101             }\r
102             return 2;\r
103         }\r
104         k = 0;\r
105         if ((x & 0xffff) == 0) {\r
106             k = 16;\r
107             x >>>= 16;\r
108         }\r
109         if ((x & 0xff) == 0) {\r
110             k += 8;\r
111             x >>>= 8;\r
112         }\r
113         if ((x & 0xf) == 0) {\r
114             k += 4;\r
115             x >>>= 4;\r
116         }\r
117         if ((x & 0x3) == 0) {\r
118             k += 2;\r
119             x >>>= 2;\r
120         }\r
121         if ((x & 1) == 0) {\r
122             k++;\r
123             x >>>= 1;\r
124             if ((x & 1) == 0)\r
125                 return 32;\r
126         }\r
127         return k;\r
128     }\r
129 \r
130         /* Return the number (0 through 32) of most significant zero bits in x. */\r
131         static int hi0bits(int x)\r
132         {\r
133             int k = 0;\r
134 \r
135             if ((x & 0xffff0000) == 0) {\r
136                 k = 16;\r
137                 x <<= 16;\r
138             }\r
139             if ((x & 0xff000000) == 0) {\r
140                 k += 8;\r
141                 x <<= 8;\r
142             }\r
143             if ((x & 0xf0000000) == 0) {\r
144                 k += 4;\r
145                 x <<= 4;\r
146             }\r
147             if ((x & 0xc0000000) == 0) {\r
148                 k += 2;\r
149                 x <<= 2;\r
150             }\r
151             if ((x & 0x80000000) == 0) {\r
152                 k++;\r
153                 if ((x & 0x40000000) == 0)\r
154                     return 32;\r
155             }\r
156             return k;\r
157         }\r
158 \r
159         static void stuffBits(byte bits[], int offset, int val)\r
160     {\r
161         bits[offset] = (byte)(val >> 24);\r
162         bits[offset + 1] = (byte)(val >> 16);\r
163         bits[offset + 2] = (byte)(val >> 8);\r
164         bits[offset + 3] = (byte)(val);\r
165     }\r
166 \r
167         /* Convert d into the form b*2^e, where b is an odd integer.  b is the returned\r
168          * Bigint and e is the returned binary exponent.  Return the number of significant\r
169          * bits in b in bits.  d must be finite and nonzero. */\r
170     static BigInteger d2b(double d, int[] e, int[] bits)\r
171     {\r
172         byte dbl_bits[];\r
173         int i, k, y, z, de;\r
174         long dBits = Double.doubleToLongBits(d);\r
175         int d0 = (int)(dBits >>> 32);\r
176         int d1 = (int)(dBits);\r
177 \r
178         z = d0 & Frac_mask;\r
179         d0 &= 0x7fffffff;   /* clear sign bit, which we ignore */\r
180 \r
181         if ((de = (int)(d0 >>> Exp_shift)) != 0)\r
182             z |= Exp_msk1;\r
183 \r
184         if ((y = d1) != 0) {\r
185                 dbl_bits = new byte[8];\r
186             k = lo0bits(y);\r
187             y >>>= k;\r
188             if (k != 0) {\r
189                 stuffBits(dbl_bits, 4, y | z << (32 - k));\r
190                 z >>= k;\r
191             }\r
192             else\r
193                 stuffBits(dbl_bits, 4, y);\r
194             stuffBits(dbl_bits, 0, z);\r
195                         i = (z != 0) ? 2 : 1;\r
196         }\r
197         else {\r
198     //        JS_ASSERT(z);\r
199                         dbl_bits = new byte[4];\r
200             k = lo0bits(z);\r
201             z >>>= k;\r
202             stuffBits(dbl_bits, 0, z);\r
203             k += 32;\r
204                         i = 1;\r
205         }\r
206         if (de != 0) {\r
207             e[0] = de - Bias - (P-1) + k;\r
208                 bits[0] = P - k;\r
209         }\r
210         else {\r
211             e[0] = de - Bias - (P-1) + 1 + k;\r
212                 bits[0] = 32*i - hi0bits(z);\r
213         }\r
214         return new BigInteger(dbl_bits);\r
215         }\r
216 \r
217     public static String JS_dtobasestr(int base, double d)\r
218     {\r
219         char[] buffer;       /* The output string */\r
220         int p;               /* index to current position in the buffer */\r
221         int pInt;            /* index to the beginning of the integer part of the string */\r
222 \r
223         int q;\r
224         int digit;\r
225         double di;           /* d truncated to an integer */\r
226         double df;           /* The fractional part of d */\r
227 \r
228 //        JS_ASSERT(base >= 2 && base <= 36);\r
229 \r
230         buffer = new char[DTOBASESTR_BUFFER_SIZE];\r
231 \r
232         p = 0;\r
233         if (d < 0.0) {\r
234             buffer[p++] = '-';\r
235             d = -d;\r
236         }\r
237 \r
238         /* Check for Infinity and NaN */\r
239         if (Double.isNaN(d))\r
240             return "NaN";\r
241         else\r
242             if (Double.isInfinite(d))\r
243                 return "Infinity";\r
244 \r
245         /* Output the integer part of d with the digits in reverse order. */\r
246         pInt = p;\r
247         di = (int)d;\r
248         BigInteger b = BigInteger.valueOf((int)di);\r
249         String intDigits = b.toString(base);\r
250         intDigits.getChars(0, intDigits.length(), buffer, p);\r
251         p += intDigits.length();\r
252 \r
253         df = d - di;\r
254         if (df != 0.0) {\r
255             /* We have a fraction. */\r
256             buffer[p++] = '.';\r
257 \r
258             long dBits = Double.doubleToLongBits(d);\r
259             int word0 = (int)(dBits >> 32);\r
260             int word1 = (int)(dBits);\r
261 \r
262             int[] e = new int[1];\r
263                         int[] bbits = new int[1];\r
264                                          \r
265                         b = d2b(df, e, bbits);\r
266 //            JS_ASSERT(e < 0);\r
267             /* At this point df = b * 2^e.  e must be less than zero because 0 < df < 1. */\r
268 \r
269             int s2 = -(word0 >>> Exp_shift1 & Exp_mask >> Exp_shift1);\r
270             if (s2 == 0)\r
271                 s2 = -1;\r
272             s2 += Bias + P;\r
273             /* 1/2^s2 = (nextDouble(d) - d)/2 */\r
274 //            JS_ASSERT(-s2 < e);\r
275             BigInteger mlo = BigInteger.valueOf(1);\r
276             BigInteger mhi = mlo;\r
277             if ((word1 == 0) && ((word0 & Bndry_mask) == 0)\r
278                 && ((word0 & (Exp_mask & Exp_mask << 1)) != 0)) {\r
279                 /* The special case.  Here we want to be within a quarter of the last input\r
280                    significant digit instead of one half of it when the output string's value is less than d.  */\r
281                 s2 += Log2P;\r
282                 mhi = BigInteger.valueOf(1<<Log2P);\r
283             }\r
284 \r
285             b = b.shiftLeft(e[0] + s2);\r
286             BigInteger s = BigInteger.valueOf(1);\r
287             s = s.shiftLeft(s2);\r
288             /* At this point we have the following:\r
289              *   s = 2^s2;\r
290              *   1 > df = b/2^s2 > 0;\r
291              *   (d - prevDouble(d))/2 = mlo/2^s2;\r
292              *   (nextDouble(d) - d)/2 = mhi/2^s2. */\r
293             BigInteger bigBase = BigInteger.valueOf(base);\r
294 \r
295             boolean done = false;\r
296             do {\r
297                 b = b.multiply(bigBase);\r
298                 BigInteger[] divResult = b.divideAndRemainder(s);\r
299                 b = divResult[1];\r
300                 digit = (char)(divResult[0].intValue());\r
301                 if (mlo == mhi)\r
302                     mlo = mhi = mlo.multiply(bigBase);\r
303                 else {\r
304                     mlo = mlo.multiply(bigBase);\r
305                     mhi = mhi.multiply(bigBase);\r
306                 }\r
307 \r
308                 /* Do we yet have the shortest string that will round to d? */\r
309                 int j = b.compareTo(mlo);\r
310                 /* j is b/2^s2 compared with mlo/2^s2. */\r
311                 BigInteger delta = s.subtract(mhi);\r
312                 int j1 = (delta.signum() <= 0) ? 1 : b.compareTo(delta);\r
313                 /* j1 is b/2^s2 compared with 1 - mhi/2^s2. */\r
314                 if (j1 == 0 && ((word1 & 1) == 0)) {\r
315                     if (j > 0)\r
316                         digit++;\r
317                     done = true;\r
318                 } else\r
319                 if (j < 0 || (j == 0 && ((word1 & 1) == 0))) {\r
320                     if (j1 > 0) {\r
321                         /* Either dig or dig+1 would work here as the least significant digit.\r
322                            Use whichever would produce an output value closer to d. */\r
323                         b = b.shiftLeft(1);\r
324                         j1 = b.compareTo(s);\r
325                         if (j1 > 0) /* The even test (|| (j1 == 0 && (digit & 1))) is not here because it messes up odd base output\r
326                                      * such as 3.5 in base 3.  */\r
327                             digit++;\r
328                     }\r
329                     done = true;\r
330                 } else if (j1 > 0) {\r
331                     digit++;\r
332                     done = true;\r
333                 }\r
334 //                JS_ASSERT(digit < (uint32)base);\r
335                 buffer[p++] = BASEDIGIT(digit);\r
336             } while (!done);\r
337         }\r
338 \r
339         return new String(buffer, 0, p);\r
340     }\r
341 \r
342         /* dtoa for IEEE arithmetic (dmg): convert double to ASCII string.\r
343          *\r
344          * Inspired by "How to Print Floating-Point Numbers Accurately" by\r
345          * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 92-101].\r
346          *\r
347          * Modifications:\r
348          *  1. Rather than iterating, we use a simple numeric overestimate\r
349          *     to determine k = floor(log10(d)).  We scale relevant\r
350          *     quantities using O(log2(k)) rather than O(k) multiplications.\r
351          *  2. For some modes > 2 (corresponding to ecvt and fcvt), we don't\r
352          *     try to generate digits strictly left to right.  Instead, we\r
353          *     compute with fewer bits and propagate the carry if necessary\r
354          *     when rounding the final digit up.  This is often faster.\r
355          *  3. Under the assumption that input will be rounded nearest,\r
356          *     mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22.\r
357          *     That is, we allow equality in stopping tests when the\r
358          *     round-nearest rule will give the same floating-point value\r
359          *     as would satisfaction of the stopping test with strict\r
360          *     inequality.\r
361          *  4. We remove common factors of powers of 2 from relevant\r
362          *     quantities.\r
363          *  5. When converting floating-point integers less than 1e16,\r
364          *     we use floating-point arithmetic rather than resorting\r
365          *     to multiple-precision integers.\r
366          *  6. When asked to produce fewer than 15 digits, we first try\r
367          *     to get by with floating-point arithmetic; we resort to\r
368          *     multiple-precision integer arithmetic only if we cannot\r
369          *     guarantee that the floating-point calculation has given\r
370          *     the correctly rounded result.  For k requested digits and\r
371          *     "uniformly" distributed input, the probability is\r
372          *     something like 10^(k-15) that we must resort to the Long\r
373          *     calculation.\r
374          */\r
375 \r
376         static int word0(double d)\r
377         {\r
378         long dBits = Double.doubleToLongBits(d);\r
379         return (int)(dBits >> 32);\r
380         }\r
381         \r
382         static double setWord0(double d, int i)\r
383         {\r
384         long dBits = Double.doubleToLongBits(d);\r
385         dBits = ((long)i << 32) | (dBits & 0x0FFFFFFFFL);\r
386                 return Double.longBitsToDouble(dBits);\r
387         }\r
388         \r
389         static int word1(double d)\r
390         {\r
391         long dBits = Double.doubleToLongBits(d);\r
392         return (int)(dBits);\r
393         }\r
394         \r
395         /* Return b * 5^k.  k must be nonnegative. */\r
396         // XXXX the C version built a cache of these\r
397         static BigInteger pow5mult(BigInteger b, int k)\r
398         {\r
399                 return b.multiply(BigInteger.valueOf(5).pow(k));\r
400         }\r
401         \r
402         static boolean roundOff(StringBuffer buf)\r
403         {\r
404                 char lastCh;\r
405                 while ((lastCh = buf.charAt(buf.length() - 1)) == '9') {\r
406                         buf.setLength(buf.length() - 1);\r
407                         if (buf.length() == 0) {\r
408                                 return true;\r
409                         }\r
410                 }\r
411                 buf.append((char)(lastCh + 1));\r
412                 return false;\r
413         }\r
414         \r
415         /* Always emits at least one digit. */\r
416         /* If biasUp is set, then rounding in modes 2 and 3 will round away from zero\r
417          * when the number is exactly halfway between two representable values.  For example, \r
418          * rounding 2.5 to zero digits after the decimal point will return 3 and not 2.\r
419          * 2.49 will still round to 2, and 2.51 will still round to 3. */\r
420         /* bufsize should be at least 20 for modes 0 and 1.  For the other modes,\r
421          * bufsize should be two greater than the maximum number of output characters expected. */\r
422         static int\r
423         JS_dtoa(double d, int mode, boolean biasUp, int ndigits,\r
424                                         boolean[] sign, StringBuffer buf)\r
425         {\r
426             /*  Arguments ndigits, decpt, sign are similar to those\r
427                 of ecvt and fcvt; trailing zeros are suppressed from\r
428                 the returned string.  If not null, *rve is set to point\r
429                 to the end of the return value.  If d is +-Infinity or NaN,\r
430                 then *decpt is set to 9999.\r
431 \r
432                 mode:\r
433                 0 ==> shortest string that yields d when read in\r
434                 and rounded to nearest.\r
435                 1 ==> like 0, but with Steele & White stopping rule;\r
436                 e.g. with IEEE P754 arithmetic , mode 0 gives\r
437                 1e23 whereas mode 1 gives 9.999999999999999e22.\r
438                 2 ==> max(1,ndigits) significant digits.  This gives a\r
439                 return value similar to that of ecvt, except\r
440                 that trailing zeros are suppressed.\r
441                 3 ==> through ndigits past the decimal point.  This\r
442                 gives a return value similar to that from fcvt,\r
443                 except that trailing zeros are suppressed, and\r
444                 ndigits can be negative.\r
445                 4-9 should give the same return values as 2-3, i.e.,\r
446                 4 <= mode <= 9 ==> same return as mode\r
447                 2 + (mode & 1).  These modes are mainly for\r
448                 debugging; often they run slower but sometimes\r
449                 faster than modes 2-3.\r
450                 4,5,8,9 ==> left-to-right digit generation.\r
451                 6-9 ==> don't try fast floating-point estimate\r
452                 (if applicable).\r
453 \r
454                 Values of mode other than 0-9 are treated as mode 0.\r
455 \r
456                 Sufficient space is allocated to the return value\r
457                 to hold the suppressed trailing zeros.\r
458             */\r
459 \r
460             int b2, b5, i, ieps, ilim, ilim0, ilim1,\r
461                 j, j1, k, k0, m2, m5, s2, s5;\r
462                 char dig;\r
463             long L;\r
464             long x;\r
465             BigInteger b, b1, delta, mlo, mhi, S;\r
466                 int[] be = new int[1];\r
467                 int[] bbits = new int[1];\r
468             double d2, ds, eps;\r
469                 boolean spec_case, denorm, k_check, try_quick, leftright;\r
470 \r
471             if ((word0(d) & Sign_bit) != 0) {\r
472                 /* set sign for everything, including 0's and NaNs */\r
473                 sign[0] = true;\r
474                 // word0(d) &= ~Sign_bit;  /* clear sign bit */\r
475                         d = setWord0(d, word0(d) & ~Sign_bit);\r
476             }\r
477             else\r
478                 sign[0] = false;\r
479 \r
480             if ((word0(d) & Exp_mask) == Exp_mask) {\r
481                 /* Infinity or NaN */\r
482                 buf.append(((word1(d) == 0) && ((word0(d) & Frac_mask) == 0)) ? "Infinity" : "NaN");\r
483                 return 9999;\r
484             }\r
485             if (d == 0) {\r
486 //            no_digits:\r
487                         buf.setLength(0);\r
488                         buf.append('0');                /* copy "0" to buffer */\r
489                 return 1;\r
490             }\r
491         \r
492                 b = d2b(d, be, bbits);\r
493                 if ((i = (int)(word0(d) >>> Exp_shift1 & (Exp_mask>>Exp_shift1))) != 0) {\r
494                         d2 = setWord0(d, (word0(d) & Frac_mask1) | Exp_11);\r
495                 /* log(x)   ~=~ log(1.5) + (x-1.5)/1.5\r
496                  * log10(x)  =  log(x) / log(10)\r
497                  *      ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10))\r
498                  * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2)\r
499                  *\r
500                  * This suggests computing an approximation k to log10(d) by\r
501                  *\r
502                  * k = (i - Bias)*0.301029995663981\r
503                  *  + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 );\r
504                  *\r
505                  * We want k to be too large rather than too small.\r
506                  * The error in the first-order Taylor series approximation\r
507                  * is in our favor, so we just round up the constant enough\r
508                  * to compensate for any error in the multiplication of\r
509                  * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077,\r
510                  * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14,\r
511                  * adding 1e-13 to the constant term more than suffices.\r
512                  * Hence we adjust the constant term to 0.1760912590558.\r
513                  * (We could get a more accurate k by invoking log10,\r
514                  *  but this is probably not worthwhile.)\r
515                  */\r
516                 i -= Bias;\r
517                 denorm = false;\r
518             }\r
519             else {\r
520                 /* d is denormalized */\r
521                 i = bbits[0] + be[0] + (Bias + (P-1) - 1);\r
522                 x = (i > 32) ? word0(d) << (64 - i) | word1(d) >>> (i - 32) : word1(d) << (32 - i);\r
523 //              d2 = x;\r
524 //              word0(d2) -= 31*Exp_msk1; /* adjust exponent */\r
525                         d2 = setWord0(x, word0(x) - 31*Exp_msk1);\r
526                 i -= (Bias + (P-1) - 1) + 1;\r
527                 denorm = true;\r
528             }\r
529             /* At this point d = f*2^i, where 1 <= f < 2.  d2 is an approximation of f. */\r
530             ds = (d2-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981;\r
531             k = (int)ds;\r
532             if (ds < 0.0 && ds != k)\r
533                 k--;    /* want k = floor(ds) */\r
534             k_check = true;\r
535             if (k >= 0 && k <= Ten_pmax) {\r
536                 if (d < tens[k])\r
537                     k--;\r
538                 k_check = false;\r
539             }\r
540             /* At this point floor(log10(d)) <= k <= floor(log10(d))+1.\r
541                If k_check is zero, we're guaranteed that k = floor(log10(d)). */\r
542             j = bbits[0] - i - 1;\r
543             /* At this point d = b/2^j, where b is an odd integer. */\r
544             if (j >= 0) {\r
545                 b2 = 0;\r
546                 s2 = j;\r
547             }\r
548             else {\r
549                 b2 = -j;\r
550                 s2 = 0;\r
551             }\r
552             if (k >= 0) {\r
553                 b5 = 0;\r
554                 s5 = k;\r
555                 s2 += k;\r
556             }\r
557             else {\r
558                 b2 -= k;\r
559                 b5 = -k;\r
560                 s5 = 0;\r
561             }\r
562             /* At this point d/10^k = (b * 2^b2 * 5^b5) / (2^s2 * 5^s5), where b is an odd integer,\r
563                b2 >= 0, b5 >= 0, s2 >= 0, and s5 >= 0. */\r
564             if (mode < 0 || mode > 9)\r
565                 mode = 0;\r
566             try_quick = true;\r
567             if (mode > 5) {\r
568                 mode -= 4;\r
569                 try_quick = false;\r
570             }\r
571             leftright = true;\r
572             ilim = ilim1 = 0;\r
573             switch(mode) {\r
574                         case 0:\r
575                         case 1:\r
576                             ilim = ilim1 = -1;\r
577                             i = 18;\r
578                             ndigits = 0;\r
579                             break;\r
580                         case 2:\r
581                             leftright = false;\r
582                             /* no break */\r
583                         case 4:\r
584                             if (ndigits <= 0)\r
585                                 ndigits = 1;\r
586                             ilim = ilim1 = i = ndigits;\r
587                             break;\r
588                         case 3:\r
589                             leftright = false;\r
590                             /* no break */\r
591                         case 5:\r
592                             i = ndigits + k + 1;\r
593                             ilim = i;\r
594                             ilim1 = i - 1;\r
595                             if (i <= 0)\r
596                                 i = 1;\r
597             }\r
598             /* ilim is the maximum number of significant digits we want, based on k and ndigits. */\r
599             /* ilim1 is the maximum number of significant digits we want, based on k and ndigits,\r
600                when it turns out that k was computed too high by one. */\r
601 \r
602                 boolean fast_failed = false;\r
603             if (ilim >= 0 && ilim <= Quick_max && try_quick) {\r
604 \r
605                 /* Try to get by with floating-point arithmetic. */\r
606 \r
607                 i = 0;\r
608                 d2 = d;\r
609                 k0 = k;\r
610                 ilim0 = ilim;\r
611                 ieps = 2; /* conservative */\r
612                 /* Divide d by 10^k, keeping track of the roundoff error and avoiding overflows. */\r
613                 if (k > 0) {\r
614                     ds = tens[k&0xf];\r
615                     j = k >> 4;\r
616                     if ((j & Bletch) != 0) {\r
617                         /* prevent overflows */\r
618                         j &= Bletch - 1;\r
619                         d /= bigtens[n_bigtens-1];\r
620                         ieps++;\r
621                     }\r
622                     for(; (j != 0); j >>= 1, i++)\r
623                         if ((j & 1) != 0) {\r
624                             ieps++;\r
625                             ds *= bigtens[i];\r
626                         }\r
627                     d /= ds;\r
628                 }\r
629                 else if ((j1 = -k) != 0) {\r
630                     d *= tens[j1 & 0xf];\r
631                     for(j = j1 >> 4; (j != 0); j >>= 1, i++)\r
632                         if ((j & 1) != 0) {\r
633                             ieps++;\r
634                             d *= bigtens[i];\r
635                         }\r
636                 }\r
637                 /* Check that k was computed correctly. */\r
638                 if (k_check && d < 1.0 && ilim > 0) {\r
639                                 if (ilim1 <= 0)\r
640                         fast_failed = true;\r
641                                 else {\r
642                                         ilim = ilim1;\r
643                                         k--;\r
644                                         d *= 10.;\r
645                                         ieps++;\r
646                                 }\r
647                 }\r
648                 /* eps bounds the cumulative error. */\r
649 //              eps = ieps*d + 7.0;\r
650 //                      word0(eps) -= (P-1)*Exp_msk1;\r
651                 eps = ieps*d + 7.0;\r
652                 eps = setWord0(eps, word0(eps) - (P-1)*Exp_msk1);\r
653                 if (ilim == 0) {\r
654                     S = mhi = null;\r
655                     d -= 5.0;\r
656                                 if (d > eps) {\r
657                                         buf.append('1');\r
658                                         k++;\r
659                                         return k + 1;\r
660                                 }\r
661                                 if (d < -eps) {\r
662                                         buf.setLength(0);\r
663                                         buf.append('0');                /* copy "0" to buffer */\r
664                                         return 1;\r
665                                 }\r
666                     fast_failed = true;\r
667                 }\r
668                         if (!fast_failed) {\r
669                                 fast_failed = true;\r
670                                 if (leftright) {\r
671                                     /* Use Steele & White method of only\r
672                                      * generating digits needed.\r
673                                      */\r
674                                     eps = 0.5/tens[ilim-1] - eps;\r
675                                     for(i = 0;;) {\r
676                                         L = (long)d;\r
677                                         d -= L;\r
678                                         buf.append((char)('0' + L));\r
679                                                 if (d < eps) {\r
680                                                         return k + 1;\r
681                                         }\r
682                                                 if (1.0 - d < eps) {\r
683 //                                          goto bump_up;\r
684                                                                 char lastCh;\r
685                                                                 while (true) {\r
686                                                                         lastCh = buf.charAt(buf.length() - 1);\r
687                                                                         buf.setLength(buf.length() - 1);\r
688                                                                         if (lastCh != '9') break;\r
689                                                                         if (buf.length() == 0) {\r
690                                                                                 k++;\r
691                                                                                 lastCh = '0';\r
692                                                                                 break;\r
693                                                                         }\r
694                                                                 }                                                               \r
695                                                                 buf.append((char)(lastCh + 1));\r
696                                                                 return k + 1;\r
697                                                 }\r
698                                         if (++i >= ilim)\r
699                                             break;\r
700                                         eps *= 10.0;\r
701                                         d *= 10.0;\r
702                                     }\r
703                                 }\r
704                                 else {\r
705                                     /* Generate ilim digits, then fix them up. */\r
706                                     eps *= tens[ilim-1];\r
707                                     for(i = 1;; i++, d *= 10.0) {\r
708                                         L = (long)d;\r
709                                         d -= L;\r
710                                         buf.append((char)('0' + L));\r
711                                         if (i == ilim) {\r
712                                                         if (d > 0.5 + eps) {\r
713 //                                              goto bump_up;\r
714                                                                 char lastCh;\r
715                                                                 while (true) {\r
716                                                                         lastCh = buf.charAt(buf.length() - 1);\r
717                                                                         buf.setLength(buf.length() - 1);\r
718                                                                         if (lastCh != '9') break;\r
719                                                                         if (buf.length() == 0) {\r
720                                                                                 k++;\r
721                                                                                 lastCh = '0';\r
722                                                                                 break;\r
723                                                                         }\r
724                                                                 }                                                               \r
725                                                                 buf.append((char)(lastCh + 1));\r
726                                                                 return k + 1;\r
727                                                         }\r
728                                                         else\r
729                                                                 if (d < 0.5 - eps) {\r
730                                                                         while (buf.charAt(buf.length() - 1) == '0')\r
731                                                                                 buf.setLength(buf.length() - 1);\r
732 //                                                                      while(*--s == '0') ;\r
733 //                                                                      s++;\r
734                                                                         return k + 1;\r
735                                                                 }\r
736                                             break;\r
737                                         }\r
738                                     }\r
739                                 }\r
740                         }\r
741                         if (fast_failed) {\r
742                                 buf.setLength(0);\r
743                                 d = d2;\r
744                                 k = k0;\r
745                                 ilim = ilim0;\r
746                         }\r
747                 }\r
748 \r
749             /* Do we have a "small" integer? */\r
750 \r
751             if (be[0] >= 0 && k <= Int_max) {\r
752                 /* Yes. */\r
753                 ds = tens[k];\r
754                 if (ndigits < 0 && ilim <= 0) {\r
755                     S = mhi = null;\r
756                                 if (ilim < 0 || d < 5*ds || (!biasUp && d == 5*ds)) {\r
757                                         buf.setLength(0);\r
758                                         buf.append('0');                /* copy "0" to buffer */\r
759                                         return 1;\r
760                                 }\r
761                                 buf.append('1');\r
762                                 k++;\r
763                                 return k + 1;\r
764                 }\r
765                 for(i = 1;; i++) {\r
766                     L = (long) (d / ds);\r
767                     d -= L*ds;\r
768                     buf.append((char)('0' + L));\r
769                     if (i == ilim) {\r
770                         d += d;\r
771                         if ((d > ds) || (d == ds && (((L & 1) != 0) || biasUp))) {\r
772 //                      bump_up:\r
773 //                          while(*--s == '9')\r
774 //                              if (s == buf) {\r
775 //                                  k++;\r
776 //                                  *s = '0';\r
777 //                                  break;\r
778 //                              }\r
779 //                          ++*s++;\r
780                                                 char lastCh;\r
781                                                 while (true) {\r
782                                                         lastCh = buf.charAt(buf.length() - 1);\r
783                                                         buf.setLength(buf.length() - 1);\r
784                                                         if (lastCh != '9') break;\r
785                                                         if (buf.length() == 0) {\r
786                                                                 k++;\r
787                                                                 lastCh = '0';\r
788                                                                 break;\r
789                                                         }\r
790                                                 }                                                               \r
791                                                 buf.append((char)(lastCh + 1));\r
792                         }\r
793                         break;\r
794                     }\r
795                                 d *= 10.0;\r
796                     if (d == 0)\r
797                         break;\r
798                 }\r
799                         return k + 1;\r
800             }\r
801 \r
802             m2 = b2;\r
803             m5 = b5;\r
804             mhi = mlo = null;\r
805             if (leftright) {\r
806                 if (mode < 2) {\r
807                     i = (denorm) ? be[0] + (Bias + (P-1) - 1 + 1) : 1 + P - bbits[0];\r
808                     /* i is 1 plus the number of trailing zero bits in d's significand. Thus,\r
809                        (2^m2 * 5^m5) / (2^(s2+i) * 5^s5) = (1/2 lsb of d)/10^k. */\r
810                 }\r
811                 else {\r
812                     j = ilim - 1;\r
813                     if (m5 >= j)\r
814                         m5 -= j;\r
815                     else {\r
816                         s5 += j -= m5;\r
817                         b5 += j;\r
818                         m5 = 0;\r
819                     }\r
820                     if ((i = ilim) < 0) {\r
821                         m2 -= i;\r
822                         i = 0;\r
823                     }\r
824                     /* (2^m2 * 5^m5) / (2^(s2+i) * 5^s5) = (1/2 * 10^(1-ilim))/10^k. */\r
825                 }\r
826                 b2 += i;\r
827                 s2 += i;\r
828             mhi = BigInteger.valueOf(1);\r
829                 /* (mhi * 2^m2 * 5^m5) / (2^s2 * 5^s5) = one-half of last printed (when mode >= 2) or\r
830                    input (when mode < 2) significant digit, divided by 10^k. */\r
831             }\r
832             /* We still have d/10^k = (b * 2^b2 * 5^b5) / (2^s2 * 5^s5).  Reduce common factors in\r
833                b2, m2, and s2 without changing the equalities. */\r
834             if (m2 > 0 && s2 > 0) {\r
835                 i = (m2 < s2) ? m2 : s2;\r
836                 b2 -= i;\r
837                 m2 -= i;\r
838                 s2 -= i;\r
839             }\r
840 \r
841             /* Fold b5 into b and m5 into mhi. */\r
842             if (b5 > 0) {\r
843                 if (leftright) {\r
844                     if (m5 > 0) {\r
845                         mhi = pow5mult(mhi, m5);\r
846                         b1 = mhi.multiply(b);\r
847                         b = b1;\r
848                     }\r
849                     if ((j = b5 - m5) != 0)\r
850                         b = pow5mult(b, j);\r
851                 }\r
852                 else\r
853                     b = pow5mult(b, b5);\r
854             }\r
855             /* Now we have d/10^k = (b * 2^b2) / (2^s2 * 5^s5) and\r
856                (mhi * 2^m2) / (2^s2 * 5^s5) = one-half of last printed or input significant digit, divided by 10^k. */\r
857 \r
858             S = BigInteger.valueOf(1);\r
859             if (s5 > 0)\r
860                 S = pow5mult(S, s5);\r
861             /* Now we have d/10^k = (b * 2^b2) / (S * 2^s2) and\r
862                (mhi * 2^m2) / (S * 2^s2) = one-half of last printed or input significant digit, divided by 10^k. */\r
863 \r
864             /* Check for special case that d is a normalized power of 2. */\r
865             spec_case = false;\r
866             if (mode < 2) {\r
867                 if ( (word1(d) == 0) && ((word0(d) & Bndry_mask) == 0)\r
868                     && ((word0(d) & (Exp_mask & Exp_mask << 1)) != 0)\r
869                     ) {\r
870                     /* The special case.  Here we want to be within a quarter of the last input\r
871                        significant digit instead of one half of it when the decimal output string's value is less than d.  */\r
872                     b2 += Log2P;\r
873                     s2 += Log2P;\r
874                     spec_case = true;\r
875                 }\r
876             }\r
877 \r
878             /* Arrange for convenient computation of quotients:\r
879              * shift left if necessary so divisor has 4 leading 0 bits.\r
880              *\r
881              * Perhaps we should just compute leading 28 bits of S once\r
882              * and for all and pass them and a shift to quorem, so it\r
883              * can do shifts and ors to compute the numerator for q.\r
884              */\r
885                 byte [] S_bytes = S.toByteArray();\r
886                 int S_hiWord = 0;\r
887                 for (int idx = 0; idx < 4; idx++) {\r
888                         S_hiWord = (S_hiWord << 8);\r
889                         if (idx < S_bytes.length)\r
890                                 S_hiWord |= (S_bytes[idx] & 0xFF);\r
891                 }       \r
892             if ((i = (((s5 != 0) ? 32 - hi0bits(S_hiWord) : 1) + s2) & 0x1f) != 0)\r
893                 i = 32 - i;\r
894             /* i is the number of leading zero bits in the most significant word of S*2^s2. */\r
895             if (i > 4) {\r
896                 i -= 4;\r
897                 b2 += i;\r
898                 m2 += i;\r
899                 s2 += i;\r
900             }\r
901             else if (i < 4) {\r
902                 i += 28;\r
903                 b2 += i;\r
904                 m2 += i;\r
905                 s2 += i;\r
906             }\r
907             /* Now S*2^s2 has exactly four leading zero bits in its most significant word. */\r
908             if (b2 > 0)\r
909                 b = b.shiftLeft(b2);\r
910             if (s2 > 0)\r
911                 S = S.shiftLeft(s2);\r
912             /* Now we have d/10^k = b/S and\r
913                (mhi * 2^m2) / S = maximum acceptable error, divided by 10^k. */\r
914             if (k_check) {\r
915                 if (b.compareTo(S) < 0) {\r
916                     k--;\r
917                     b = b.multiply(BigInteger.valueOf(10));  /* we botched the k estimate */\r
918                     if (leftright)\r
919                         mhi = mhi.multiply(BigInteger.valueOf(10));\r
920                     ilim = ilim1;\r
921                 }\r
922             }\r
923             /* At this point 1 <= d/10^k = b/S < 10. */\r
924 \r
925             if (ilim <= 0 && mode > 2) {\r
926                 /* We're doing fixed-mode output and d is less than the minimum nonzero output in this mode.\r
927                    Output either zero or the minimum nonzero output depending on which is closer to d. */\r
928                 if ((ilim < 0 )\r
929                                         || ((i = b.compareTo(S = S.multiply(BigInteger.valueOf(5)))) < 0)\r
930                                         || ((i == 0 && !biasUp))) {\r
931                 /* Always emit at least one digit.  If the number appears to be zero\r
932                    using the current mode, then emit one '0' digit and set decpt to 1. */\r
933                 /*no_digits:\r
934                     k = -1 - ndigits;\r
935                     goto ret; */\r
936                                 buf.setLength(0);\r
937                                 buf.append('0');                /* copy "0" to buffer */\r
938                                 return 1;\r
939 //                  goto no_digits;\r
940                 }\r
941 //          one_digit:\r
942                 buf.append('1');\r
943                 k++;\r
944                         return k + 1;\r
945             }\r
946             if (leftright) {\r
947                 if (m2 > 0)\r
948                     mhi = mhi.shiftLeft(m2);\r
949 \r
950                 /* Compute mlo -- check for special case\r
951                  * that d is a normalized power of 2.\r
952                  */\r
953 \r
954                 mlo = mhi;\r
955                 if (spec_case) {\r
956                     mhi = mlo;\r
957                     mhi = mhi.shiftLeft(Log2P);\r
958                 }\r
959                 /* mlo/S = maximum acceptable error, divided by 10^k, if the output is less than d. */\r
960                 /* mhi/S = maximum acceptable error, divided by 10^k, if the output is greater than d. */\r
961 \r
962                 for(i = 1;;i++) {                               \r
963                                 BigInteger[] divResult = b.divideAndRemainder(S);\r
964                                 b = divResult[1];                               \r
965                     dig = (char)(divResult[0].intValue() + '0');\r
966                     /* Do we yet have the shortest decimal string\r
967                      * that will round to d?\r
968                      */\r
969                     j = b.compareTo(mlo);\r
970                     /* j is b/S compared with mlo/S. */\r
971                     delta = S.subtract(mhi);\r
972                     j1 = (delta.signum() <= 0) ? 1 : b.compareTo(delta);\r
973                     /* j1 is b/S compared with 1 - mhi/S. */\r
974                     if ((j1 == 0) && (mode == 0) && ((word1(d) & 1) == 0)) {\r
975                                         if (dig == '9') {\r
976                                                 buf.append('9');\r
977                                                 if (roundOff(buf)) {\r
978                                                         k++;\r
979                                                         buf.append('1');\r
980                                                 }\r
981                                                 return k + 1;\r
982 //                          goto round_9_up;\r
983                                         }\r
984                         if (j > 0)\r
985                             dig++;\r
986                         buf.append(dig);\r
987                                         return k + 1;\r
988                     }\r
989                     if ((j < 0) \r
990                                                 || ((j == 0) \r
991                                                         && (mode == 0)\r
992                                                         && ((word1(d) & 1) == 0)\r
993                         )) {\r
994                         if (j1 > 0) {\r
995                             /* Either dig or dig+1 would work here as the least significant decimal digit.\r
996                                Use whichever would produce a decimal value closer to d. */\r
997                             b = b.shiftLeft(1);\r
998                             j1 = b.compareTo(S);\r
999                             if (((j1 > 0) || (j1 == 0 && (((dig & 1) == 1) || biasUp)))\r
1000                                                         && (dig++ == '9')) {\r
1001                                                                 buf.append('9');\r
1002                                                                 if (roundOff(buf)) {\r
1003                                                                         k++;\r
1004                                                                         buf.append('1');\r
1005                                                                 }\r
1006                                                                 return k + 1;\r
1007 //                                          goto round_9_up;\r
1008                                                 }\r
1009                         }\r
1010                         buf.append(dig);\r
1011                                         return k + 1;\r
1012                     }\r
1013                     if (j1 > 0) {\r
1014                         if (dig == '9') { /* possible if i == 1 */\r
1015 //                      round_9_up:\r
1016 //                          *s++ = '9';\r
1017 //                          goto roundoff;\r
1018                                                 buf.append('9');\r
1019                                                 if (roundOff(buf)) {\r
1020                                                         k++;\r
1021                                                         buf.append('1');\r
1022                                                 }                       \r
1023                                                 return k + 1;\r
1024                         }\r
1025                         buf.append((char)(dig + 1));\r
1026                                         return k + 1;\r
1027                     }\r
1028                     buf.append(dig);\r
1029                     if (i == ilim)\r
1030                         break;\r
1031                     b = b.multiply(BigInteger.valueOf(10));\r
1032                     if (mlo == mhi)\r
1033                         mlo = mhi = mhi.multiply(BigInteger.valueOf(10));\r
1034                     else {\r
1035                         mlo = mlo.multiply(BigInteger.valueOf(10));\r
1036                         mhi = mhi.multiply(BigInteger.valueOf(10));\r
1037                     }\r
1038                 }\r
1039             }\r
1040             else\r
1041                 for(i = 1;; i++) {\r
1042 //                  (char)(dig = quorem(b,S) + '0');\r
1043                                 BigInteger[] divResult = b.divideAndRemainder(S);\r
1044                                 b = divResult[1];                               \r
1045                     dig = (char)(divResult[0].intValue() + '0');\r
1046                             buf.append(dig);\r
1047                     if (i >= ilim)\r
1048                         break;\r
1049                     b = b.multiply(BigInteger.valueOf(10));\r
1050                 }\r
1051 \r
1052             /* Round off last digit */\r
1053 \r
1054             b = b.shiftLeft(1);\r
1055             j = b.compareTo(S);\r
1056             if ((j > 0) || (j == 0 && (((dig & 1) == 1) || biasUp))) {\r
1057 //          roundoff:\r
1058 //              while(*--s == '9')\r
1059 //                  if (s == buf) {\r
1060 //                      k++;\r
1061 //                      *s++ = '1';\r
1062 //                      goto ret;\r
1063 //                  }\r
1064 //              ++*s++;\r
1065                         if (roundOff(buf)) {\r
1066                                 k++;\r
1067                                 buf.append('1');\r
1068                                 return k + 1;\r
1069                         }                       \r
1070             }\r
1071             else {\r
1072                 /* Strip trailing zeros */\r
1073                         while (buf.charAt(buf.length() - 1) == '0')\r
1074                                 buf.setLength(buf.length() - 1);\r
1075 //              while(*--s == '0') ;\r
1076 //              s++;\r
1077             }\r
1078 //        ret:\r
1079 //          Bfree(S);\r
1080 //          if (mhi) {\r
1081 //              if (mlo && mlo != mhi)\r
1082 //                  Bfree(mlo);\r
1083 //              Bfree(mhi);\r
1084 //          }\r
1085 //        ret1:\r
1086 //          Bfree(b);\r
1087 //          JS_ASSERT(s < buf + bufsize);\r
1088             return k + 1;\r
1089         }\r
1090 \r
1091         /* Mapping of JSDToStrMode -> JS_dtoa mode */\r
1092         private static final int dtoaModes[] = {\r
1093             0,   /* DTOSTR_STANDARD */\r
1094             0,   /* DTOSTR_STANDARD_EXPONENTIAL, */\r
1095             3,   /* DTOSTR_FIXED, */\r
1096             2,   /* DTOSTR_EXPONENTIAL, */\r
1097             2};  /* DTOSTR_PRECISION */\r
1098 \r
1099         static void\r
1100         JS_dtostr(StringBuffer buffer, int mode, int precision, double d)\r
1101         {\r
1102             int decPt;                                                                  /* Position of decimal point relative to first digit returned by JS_dtoa */\r
1103             boolean[] sign = new boolean[1];                    /* true if the sign bit was set in d */\r
1104             int nDigits;                                                                /* Number of significand digits returned by JS_dtoa */\r
1105 \r
1106 //          JS_ASSERT(bufferSize >= (size_t)(mode <= DTOSTR_STANDARD_EXPONENTIAL ? DTOSTR_STANDARD_BUFFER_SIZE :\r
1107 //                  DTOSTR_VARIABLE_BUFFER_SIZE(precision)));\r
1108 \r
1109             if (mode == DTOSTR_FIXED && (d >= 1e21 || d <= -1e21))\r
1110                 mode = DTOSTR_STANDARD; /* Change mode here rather than below because the buffer may not be large enough to hold a large integer. */\r
1111 \r
1112             decPt = JS_dtoa(d, dtoaModes[mode], mode >= DTOSTR_FIXED, precision, sign, buffer);\r
1113                 nDigits = buffer.length();\r
1114 \r
1115             /* If Infinity, -Infinity, or NaN, return the string regardless of the mode. */\r
1116             if (decPt != 9999) {\r
1117                 boolean exponentialNotation = false;\r
1118                 int minNDigits = 0;         /* Minimum number of significand digits required by mode and precision */\r
1119                 int p;\r
1120                 int q;\r
1121 \r
1122                 switch (mode) {\r
1123                     case DTOSTR_STANDARD:\r
1124                         if (decPt < -5 || decPt > 21)\r
1125                             exponentialNotation = true;\r
1126                         else\r
1127                             minNDigits = decPt;\r
1128                         break;\r
1129 \r
1130                     case DTOSTR_FIXED:\r
1131                         if (precision >= 0)\r
1132                             minNDigits = decPt + precision;\r
1133                         else\r
1134                             minNDigits = decPt;\r
1135                         break;\r
1136 \r
1137                     case DTOSTR_EXPONENTIAL:\r
1138 //                      JS_ASSERT(precision > 0);\r
1139                         minNDigits = precision;\r
1140                         /* Fall through */\r
1141                     case DTOSTR_STANDARD_EXPONENTIAL:\r
1142                         exponentialNotation = true;\r
1143                         break;\r
1144 \r
1145                     case DTOSTR_PRECISION:\r
1146 //                      JS_ASSERT(precision > 0);\r
1147                         minNDigits = precision;\r
1148                         if (decPt < -5 || decPt > precision)\r
1149                             exponentialNotation = true;\r
1150                         break;\r
1151                 }\r
1152 \r
1153                 /* If the number has fewer than minNDigits, pad it with zeros at the end */\r
1154                 if (nDigits < minNDigits) {\r
1155                     p = minNDigits;\r
1156                     nDigits = minNDigits;\r
1157                     do {\r
1158                                         buffer.append('0');\r
1159                     } while (buffer.length() != p);\r
1160                 }\r
1161                 \r
1162                 if (exponentialNotation) {\r
1163                     /* Insert a decimal point if more than one significand digit */\r
1164                     if (nDigits != 1) {\r
1165                                         buffer.insert(1, '.');\r
1166                     }\r
1167                                 buffer.append('e');\r
1168                                 if ((decPt - 1) >= 0)\r
1169                                         buffer.append('+');\r
1170                                 buffer.append(decPt - 1);\r
1171 //                  JS_snprintf(numEnd, bufferSize - (numEnd - buffer), "e%+d", decPt-1);\r
1172                 } else if (decPt != nDigits) {\r
1173                     /* Some kind of a fraction in fixed notation */\r
1174 //                  JS_ASSERT(decPt <= nDigits);\r
1175                     if (decPt > 0) {\r
1176                         /* dd...dd . dd...dd */\r
1177                                         buffer.insert(decPt, '.');\r
1178                     } else {\r
1179                         /* 0 . 00...00dd...dd */\r
1180                                         for (int i = 0; i < 1 - decPt; i++)\r
1181                                                 buffer.insert(0, '0');\r
1182                                         buffer.insert(1, '.');\r
1183                     }\r
1184                 }\r
1185             }\r
1186 \r
1187             /* If negative and neither -0.0 nor NaN, output a leading '-'. */\r
1188             if (sign[0] &&\r
1189                     !(word0(d) == Sign_bit && word1(d) == 0) &&\r
1190                     !((word0(d) & Exp_mask) == Exp_mask &&\r
1191                       ((word1(d) != 0) || ((word0(d) & Frac_mask) != 0)))) {\r
1192                 buffer.insert(0, '-');\r
1193             }\r
1194         }\r
1195 \r
1196 }\r
1197 \r