KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > google > gwt > dev > js > rhino > DToA


1 /* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2  *
3  * The contents of this file are subject to the Netscape Public
4  * License Version 1.1 (the "License"); you may not use this file
5  * except in compliance with the License. You may obtain a copy of
6  * the License at http://www.mozilla.org/NPL/
7  *
8  * Software distributed under the License is distributed on an "AS
9  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
10  * implied. See the License for the specific language governing
11  * rights and limitations under the License.
12  *
13  * The Original Code is Rhino code, released
14  * May 6, 1999.
15  *
16  * The Initial Developer of the Original Code is Netscape
17  * Communications Corporation. Portions created by Netscape are
18  * Copyright (C) 1997-1999 Netscape Communications Corporation. All
19  * Rights Reserved.
20  *
21  * Contributor(s):
22  * Waldemar Horwat
23  * Roger Lawrence
24  *
25  * Alternatively, the contents of this file may be used under the
26  * terms of the GNU Public License (the "GPL"), in which case the
27  * provisions of the GPL are applicable instead of those above.
28  * If you wish to allow use of your version of this file only
29  * under the terms of the GPL and not to allow others to use your
30  * version of this file under the NPL, indicate your decision by
31  * deleting the provisions above and replace them with the notice
32  * and other provisions required by the GPL. If you do not delete
33  * the provisions above, a recipient may use your version of this
34  * file under either the NPL or the GPL.
35  */

36 // Modified by Google
37

38 /****************************************************************
39   *
40   * The author of this software is David M. Gay.
41   *
42   * Copyright (c) 1991, 2000, 2001 by Lucent Technologies.
43   *
44   * Permission to use, copy, modify, and distribute this software for any
45   * purpose without fee is hereby granted, provided that this entire notice
46   * is included in all copies of any software which is or includes a copy
47   * or modification of this software and in all copies of the supporting
48   * documentation for such software.
49   *
50   * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
51   * WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR LUCENT MAKES ANY
52   * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
53   * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
54   *
55   ***************************************************************/

56
57 package com.google.gwt.dev.js.rhino;
58
59 import java.math.BigInteger JavaDoc;
60
61 class DToA {
62
63
64 /* "-0.0000...(1073 zeros after decimal point)...0001\0" is the longest string that we could produce,
65  * which occurs when printing -5e-324 in binary. We could compute a better estimate of the size of
66  * the output string and malloc fewer bytes depending on d and base, but why bother? */

67
68     static final int DTOBASESTR_BUFFER_SIZE = 1078;
69
70     static char BASEDIGIT(int digit) {
71         return (char)((digit >= 10) ? 'a' - 10 + digit : '0' + digit);
72     }
73
74     static final int
75         DTOSTR_STANDARD = 0, /* Either fixed or exponential format; round-trip */
76         DTOSTR_STANDARD_EXPONENTIAL = 1, /* Always exponential format; round-trip */
77         DTOSTR_FIXED = 2, /* Round to <precision> digits after the decimal point; exponential if number is large */
78         DTOSTR_EXPONENTIAL = 3, /* Always exponential format; <precision> significant digits */
79         DTOSTR_PRECISION = 4; /* Either fixed or exponential format; <precision> significant digits */
80
81
82     static final int Frac_mask = 0xfffff;
83     static final int Exp_shift = 20;
84     static final int Exp_msk1 = 0x100000;
85     static final int Bias = 1023;
86     static final int P = 53;
87
88     static final int Exp_shift1 = 20;
89     static final int Exp_mask = 0x7ff00000;
90     static final int Bndry_mask = 0xfffff;
91     static final int Log2P = 1;
92
93     static final int Sign_bit = 0x80000000;
94     static final int Exp_11 = 0x3ff00000;
95     static final int Ten_pmax = 22;
96     static final int Quick_max = 14;
97     static final int Bletch = 0x10;
98     static final int Frac_mask1 = 0xfffff;
99     static final int Int_max = 14;
100     static final int n_bigtens = 5;
101
102
103     static final double tens[] = {
104         1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
105         1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
106         1e20, 1e21, 1e22
107     };
108
109     static final double bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 };
110
111     static int lo0bits(int y)
112     {
113         int k;
114         int x = y;
115
116         if ((x & 7) != 0) {
117             if ((x & 1) != 0)
118                 return 0;
119             if ((x & 2) != 0) {
120                 return 1;
121             }
122             return 2;
123         }
124         k = 0;
125         if ((x & 0xffff) == 0) {
126             k = 16;
127             x >>>= 16;
128         }
129         if ((x & 0xff) == 0) {
130             k += 8;
131             x >>>= 8;
132         }
133         if ((x & 0xf) == 0) {
134             k += 4;
135             x >>>= 4;
136         }
137         if ((x & 0x3) == 0) {
138             k += 2;
139             x >>>= 2;
140         }
141         if ((x & 1) == 0) {
142             k++;
143             x >>>= 1;
144             if ((x & 1) == 0)
145                 return 32;
146         }
147         return k;
148     }
149
150     /* Return the number (0 through 32) of most significant zero bits in x. */
151     static int hi0bits(int x)
152     {
153         int k = 0;
154
155         if ((x & 0xffff0000) == 0) {
156             k = 16;
157             x <<= 16;
158         }
159         if ((x & 0xff000000) == 0) {
160             k += 8;
161             x <<= 8;
162         }
163         if ((x & 0xf0000000) == 0) {
164             k += 4;
165             x <<= 4;
166         }
167         if ((x & 0xc0000000) == 0) {
168             k += 2;
169             x <<= 2;
170         }
171         if ((x & 0x80000000) == 0) {
172             k++;
173             if ((x & 0x40000000) == 0)
174                 return 32;
175         }
176         return k;
177     }
178
179     static void stuffBits(byte bits[], int offset, int val)
180     {
181         bits[offset] = (byte)(val >> 24);
182         bits[offset + 1] = (byte)(val >> 16);
183         bits[offset + 2] = (byte)(val >> 8);
184         bits[offset + 3] = (byte)(val);
185     }
186
187     /* Convert d into the form b*2^e, where b is an odd integer. b is the returned
188      * Bigint and e is the returned binary exponent. Return the number of significant
189      * bits in b in bits. d must be finite and nonzero. */

190     static BigInteger JavaDoc d2b(double d, int[] e, int[] bits)
191     {
192         byte dbl_bits[];
193         int i, k, y, z, de;
194         long dBits = Double.doubleToLongBits(d);
195         int d0 = (int)(dBits >>> 32);
196         int d1 = (int)(dBits);
197
198         z = d0 & Frac_mask;
199         d0 &= 0x7fffffff; /* clear sign bit, which we ignore */
200
201         if ((de = (int)(d0 >>> Exp_shift)) != 0)
202             z |= Exp_msk1;
203
204         if ((y = d1) != 0) {
205             dbl_bits = new byte[8];
206             k = lo0bits(y);
207             y >>>= k;
208             if (k != 0) {
209                 stuffBits(dbl_bits, 4, y | z << (32 - k));
210                 z >>= k;
211             }
212             else
213                 stuffBits(dbl_bits, 4, y);
214             stuffBits(dbl_bits, 0, z);
215             i = (z != 0) ? 2 : 1;
216         }
217         else {
218     // JS_ASSERT(z);
219
dbl_bits = new byte[4];
220             k = lo0bits(z);
221             z >>>= k;
222             stuffBits(dbl_bits, 0, z);
223             k += 32;
224             i = 1;
225         }
226         if (de != 0) {
227             e[0] = de - Bias - (P-1) + k;
228             bits[0] = P - k;
229         }
230         else {
231             e[0] = de - Bias - (P-1) + 1 + k;
232             bits[0] = 32*i - hi0bits(z);
233         }
234         return new BigInteger JavaDoc(dbl_bits);
235     }
236
237     public static String JavaDoc JS_dtobasestr(int base, double d)
238     {
239         char[] buffer; /* The output string */
240         int p; /* index to current position in the buffer */
241         int pInt; /* index to the beginning of the integer part of the string */
242
243         int q;
244         int digit;
245         double di; /* d truncated to an integer */
246         double df; /* The fractional part of d */
247
248 // JS_ASSERT(base >= 2 && base <= 36);
249

250         buffer = new char[DTOBASESTR_BUFFER_SIZE];
251
252         p = 0;
253         if (d < 0.0) {
254             buffer[p++] = '-';
255             d = -d;
256         }
257
258         /* Check for Infinity and NaN */
259         if (Double.isNaN(d))
260             return "NaN";
261         else
262             if (Double.isInfinite(d))
263                 return "Infinity";
264
265         /* Output the integer part of d with the digits in reverse order. */
266         pInt = p;
267         di = (int)d;
268         BigInteger JavaDoc b = BigInteger.valueOf((int)di);
269         String JavaDoc intDigits = b.toString(base);
270         intDigits.getChars(0, intDigits.length(), buffer, p);
271         p += intDigits.length();
272
273         df = d - di;
274         if (df != 0.0) {
275             /* We have a fraction. */
276             buffer[p++] = '.';
277
278             long dBits = Double.doubleToLongBits(d);
279             int word0 = (int)(dBits >> 32);
280             int word1 = (int)(dBits);
281
282             int[] e = new int[1];
283             int[] bbits = new int[1];
284
285             b = d2b(df, e, bbits);
286 // JS_ASSERT(e < 0);
287
/* At this point df = b * 2^e. e must be less than zero because 0 < df < 1. */
288
289             int s2 = -(word0 >>> Exp_shift1 & Exp_mask >> Exp_shift1);
290             if (s2 == 0)
291                 s2 = -1;
292             s2 += Bias + P;
293             /* 1/2^s2 = (nextDouble(d) - d)/2 */
294 // JS_ASSERT(-s2 < e);
295
BigInteger JavaDoc mlo = BigInteger.valueOf(1);
296             BigInteger JavaDoc mhi = mlo;
297             if ((word1 == 0) && ((word0 & Bndry_mask) == 0)
298                 && ((word0 & (Exp_mask & Exp_mask << 1)) != 0)) {
299                 /* The special case. Here we want to be within a quarter of the last input
300                    significant digit instead of one half of it when the output string's value is less than d. */

301                 s2 += Log2P;
302                 mhi = BigInteger.valueOf(1<<Log2P);
303             }
304
305             b = b.shiftLeft(e[0] + s2);
306             BigInteger JavaDoc s = BigInteger.valueOf(1);
307             s = s.shiftLeft(s2);
308             /* At this point we have the following:
309              * s = 2^s2;
310              * 1 > df = b/2^s2 > 0;
311              * (d - prevDouble(d))/2 = mlo/2^s2;
312              * (nextDouble(d) - d)/2 = mhi/2^s2. */

313             BigInteger JavaDoc bigBase = BigInteger.valueOf(base);
314
315             boolean done = false;
316             do {
317                 b = b.multiply(bigBase);
318                 BigInteger JavaDoc[] divResult = b.divideAndRemainder(s);
319                 b = divResult[1];
320                 digit = (char)(divResult[0].intValue());
321                 if (mlo == mhi)
322                     mlo = mhi = mlo.multiply(bigBase);
323                 else {
324                     mlo = mlo.multiply(bigBase);
325                     mhi = mhi.multiply(bigBase);
326                 }
327
328                 /* Do we yet have the shortest string that will round to d? */
329                 int j = b.compareTo(mlo);
330                 /* j is b/2^s2 compared with mlo/2^s2. */
331                 BigInteger JavaDoc delta = s.subtract(mhi);
332                 int j1 = (delta.signum() <= 0) ? 1 : b.compareTo(delta);
333                 /* j1 is b/2^s2 compared with 1 - mhi/2^s2. */
334                 if (j1 == 0 && ((word1 & 1) == 0)) {
335                     if (j > 0)
336                         digit++;
337                     done = true;
338                 } else
339                 if (j < 0 || (j == 0 && ((word1 & 1) == 0))) {
340                     if (j1 > 0) {
341                         /* Either dig or dig+1 would work here as the least significant digit.
342                            Use whichever would produce an output value closer to d. */

343                         b = b.shiftLeft(1);
344                         j1 = b.compareTo(s);
345                         if (j1 > 0) /* The even test (|| (j1 == 0 && (digit & 1))) is not here because it messes up odd base output
346                                      * such as 3.5 in base 3. */

347                             digit++;
348                     }
349                     done = true;
350                 } else if (j1 > 0) {
351                     digit++;
352                     done = true;
353                 }
354 // JS_ASSERT(digit < (uint32)base);
355
buffer[p++] = BASEDIGIT(digit);
356             } while (!done);
357         }
358
359         return new String JavaDoc(buffer, 0, p);
360     }
361
362     /* dtoa for IEEE arithmetic (dmg): convert double to ASCII string.
363      *
364      * Inspired by "How to Print Floating-Point Numbers Accurately" by
365      * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 92-101].
366      *
367      * Modifications:
368      * 1. Rather than iterating, we use a simple numeric overestimate
369      * to determine k = floor(log10(d)). We scale relevant
370      * quantities using O(log2(k)) rather than O(k) multiplications.
371      * 2. For some modes > 2 (corresponding to ecvt and fcvt), we don't
372      * try to generate digits strictly left to right. Instead, we
373      * compute with fewer bits and propagate the carry if necessary
374      * when rounding the final digit up. This is often faster.
375      * 3. Under the assumption that input will be rounded nearest,
376      * mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22.
377      * That is, we allow equality in stopping tests when the
378      * round-nearest rule will give the same floating-point value
379      * as would satisfaction of the stopping test with strict
380      * inequality.
381      * 4. We remove common factors of powers of 2 from relevant
382      * quantities.
383      * 5. When converting floating-point integers less than 1e16,
384      * we use floating-point arithmetic rather than resorting
385      * to multiple-precision integers.
386      * 6. When asked to produce fewer than 15 digits, we first try
387      * to get by with floating-point arithmetic; we resort to
388      * multiple-precision integer arithmetic only if we cannot
389      * guarantee that the floating-point calculation has given
390      * the correctly rounded result. For k requested digits and
391      * "uniformly" distributed input, the probability is
392      * something like 10^(k-15) that we must resort to the Long
393      * calculation.
394      */

395
396     static int word0(double d)
397     {
398         long dBits = Double.doubleToLongBits(d);
399         return (int)(dBits >> 32);
400     }
401
402     static double setWord0(double d, int i)
403     {
404         long dBits = Double.doubleToLongBits(d);
405         dBits = ((long)i << 32) | (dBits & 0x0FFFFFFFFL);
406         return Double.longBitsToDouble(dBits);
407     }
408
409     static int word1(double d)
410     {
411         long dBits = Double.doubleToLongBits(d);
412         return (int)(dBits);
413     }
414
415     /* Return b * 5^k. k must be nonnegative. */
416     // XXXX the C version built a cache of these
417
static BigInteger JavaDoc pow5mult(BigInteger JavaDoc b, int k)
418     {
419         return b.multiply(BigInteger.valueOf(5).pow(k));
420     }
421
422     static boolean roundOff(StringBuffer JavaDoc buf)
423     {
424         char lastCh;
425         while ((lastCh = buf.charAt(buf.length() - 1)) == '9') {
426             buf.setLength(buf.length() - 1);
427             if (buf.length() == 0) {
428                 return true;
429             }
430         }
431         buf.append((char)(lastCh + 1));
432         return false;
433     }
434
435     /* Always emits at least one digit. */
436     /* If biasUp is set, then rounding in modes 2 and 3 will round away from zero
437      * when the number is exactly halfway between two representable values. For example,
438      * rounding 2.5 to zero digits after the decimal point will return 3 and not 2.
439      * 2.49 will still round to 2, and 2.51 will still round to 3. */

440     /* bufsize should be at least 20 for modes 0 and 1. For the other modes,
441      * bufsize should be two greater than the maximum number of output characters expected. */

442     static int
443     JS_dtoa(double d, int mode, boolean biasUp, int ndigits,
444                     boolean[] sign, StringBuffer JavaDoc buf)
445     {
446         /* Arguments ndigits, decpt, sign are similar to those
447             of ecvt and fcvt; trailing zeros are suppressed from
448             the returned string. If not null, *rve is set to point
449             to the end of the return value. If d is +-Infinity or NaN,
450             then *decpt is set to 9999.
451
452             mode:
453             0 ==> shortest string that yields d when read in
454             and rounded to nearest.
455             1 ==> like 0, but with Steele & White stopping rule;
456             e.g. with IEEE P754 arithmetic , mode 0 gives
457             1e23 whereas mode 1 gives 9.999999999999999e22.
458             2 ==> max(1,ndigits) significant digits. This gives a
459             return value similar to that of ecvt, except
460             that trailing zeros are suppressed.
461             3 ==> through ndigits past the decimal point. This
462             gives a return value similar to that from fcvt,
463             except that trailing zeros are suppressed, and
464             ndigits can be negative.
465             4-9 should give the same return values as 2-3, i.e.,
466             4 <= mode <= 9 ==> same return as mode
467             2 + (mode & 1). These modes are mainly for
468             debugging; often they run slower but sometimes
469             faster than modes 2-3.
470             4,5,8,9 ==> left-to-right digit generation.
471             6-9 ==> don't try fast floating-point estimate
472             (if applicable).
473
474             Values of mode other than 0-9 are treated as mode 0.
475
476             Sufficient space is allocated to the return value
477             to hold the suppressed trailing zeros.
478         */

479
480         int b2, b5, i, ieps, ilim, ilim0, ilim1,
481             j, j1, k, k0, m2, m5, s2, s5;
482         char dig;
483         long L;
484         long x;
485         BigInteger JavaDoc b, b1, delta, mlo, mhi, S;
486         int[] be = new int[1];
487         int[] bbits = new int[1];
488         double d2, ds, eps;
489         boolean spec_case, denorm, k_check, try_quick, leftright;
490
491         if ((word0(d) & Sign_bit) != 0) {
492             /* set sign for everything, including 0's and NaNs */
493             sign[0] = true;
494             // word0(d) &= ~Sign_bit; /* clear sign bit */
495
d = setWord0(d, word0(d) & ~Sign_bit);
496         }
497         else
498             sign[0] = false;
499
500         if ((word0(d) & Exp_mask) == Exp_mask) {
501             /* Infinity or NaN */
502             buf.append(((word1(d) == 0) && ((word0(d) & Frac_mask) == 0)) ? "Infinity" : "NaN");
503             return 9999;
504         }
505         if (d == 0) {
506 // no_digits:
507
buf.setLength(0);
508             buf.append('0'); /* copy "0" to buffer */
509             return 1;
510         }
511
512         b = d2b(d, be, bbits);
513         if ((i = (int)(word0(d) >>> Exp_shift1 & (Exp_mask>>Exp_shift1))) != 0) {
514             d2 = setWord0(d, (word0(d) & Frac_mask1) | Exp_11);
515             /* log(x) ~=~ log(1.5) + (x-1.5)/1.5
516              * log10(x) = log(x) / log(10)
517              * ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10))
518              * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2)
519              *
520              * This suggests computing an approximation k to log10(d) by
521              *
522              * k = (i - Bias)*0.301029995663981
523              * + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 );
524              *
525              * We want k to be too large rather than too small.
526              * The error in the first-order Taylor series approximation
527              * is in our favor, so we just round up the constant enough
528              * to compensate for any error in the multiplication of
529              * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077,
530              * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14,
531              * adding 1e-13 to the constant term more than suffices.
532              * Hence we adjust the constant term to 0.1760912590558.
533              * (We could get a more accurate k by invoking log10,
534              * but this is probably not worthwhile.)
535              */

536             i -= Bias;
537             denorm = false;
538         }
539         else {
540             /* d is denormalized */
541             i = bbits[0] + be[0] + (Bias + (P-1) - 1);
542             x = (i > 32) ? word0(d) << (64 - i) | word1(d) >>> (i - 32) : word1(d) << (32 - i);
543 // d2 = x;
544
// word0(d2) -= 31*Exp_msk1; /* adjust exponent */
545
d2 = setWord0(x, word0(x) - 31*Exp_msk1);
546             i -= (Bias + (P-1) - 1) + 1;
547             denorm = true;
548         }
549         /* At this point d = f*2^i, where 1 <= f < 2. d2 is an approximation of f. */
550         ds = (d2-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981;
551         k = (int)ds;
552         if (ds < 0.0 && ds != k)
553             k--; /* want k = floor(ds) */
554         k_check = true;
555         if (k >= 0 && k <= Ten_pmax) {
556             if (d < tens[k])
557                 k--;
558             k_check = false;
559         }
560         /* At this point floor(log10(d)) <= k <= floor(log10(d))+1.
561            If k_check is zero, we're guaranteed that k = floor(log10(d)). */

562         j = bbits[0] - i - 1;
563         /* At this point d = b/2^j, where b is an odd integer. */
564         if (j >= 0) {
565             b2 = 0;
566             s2 = j;
567         }
568         else {
569             b2 = -j;
570             s2 = 0;
571         }
572         if (k >= 0) {
573             b5 = 0;
574             s5 = k;
575             s2 += k;
576         }
577         else {
578             b2 -= k;
579             b5 = -k;
580             s5 = 0;
581         }
582         /* At this point d/10^k = (b * 2^b2 * 5^b5) / (2^s2 * 5^s5), where b is an odd integer,
583            b2 >= 0, b5 >= 0, s2 >= 0, and s5 >= 0. */

584         if (mode < 0 || mode > 9)
585             mode = 0;
586         try_quick = true;
587         if (mode > 5) {
588             mode -= 4;
589             try_quick = false;
590         }
591         leftright = true;
592         ilim = ilim1 = 0;
593         switch(mode) {
594             case 0:
595             case 1:
596                 ilim = ilim1 = -1;
597                 i = 18;
598                 ndigits = 0;
599                 break;
600             case 2:
601                 leftright = false;
602                 /* no break */
603             case 4:
604                 if (ndigits <= 0)
605                     ndigits = 1;
606                 ilim = ilim1 = i = ndigits;
607                 break;
608             case 3:
609                 leftright = false;
610                 /* no break */
611             case 5:
612                 i = ndigits + k + 1;
613                 ilim = i;
614                 ilim1 = i - 1;
615                 if (i <= 0)
616                     i = 1;
617         }
618         /* ilim is the maximum number of significant digits we want, based on k and ndigits. */
619         /* ilim1 is the maximum number of significant digits we want, based on k and ndigits,
620            when it turns out that k was computed too high by one. */

621
622         boolean fast_failed = false;
623         if (ilim >= 0 && ilim <= Quick_max && try_quick) {
624
625             /* Try to get by with floating-point arithmetic. */
626
627             i = 0;
628             d2 = d;
629             k0 = k;
630             ilim0 = ilim;
631             ieps = 2; /* conservative */
632             /* Divide d by 10^k, keeping track of the roundoff error and avoiding overflows. */
633             if (k > 0) {
634                 ds = tens[k&0xf];
635                 j = k >> 4;
636                 if ((j & Bletch) != 0) {
637                     /* prevent overflows */
638                     j &= Bletch - 1;
639                     d /= bigtens[n_bigtens-1];
640                     ieps++;
641                 }
642                 for(; (j != 0); j >>= 1, i++)
643                     if ((j & 1) != 0) {
644                         ieps++;
645                         ds *= bigtens[i];
646                     }
647                 d /= ds;
648             }
649             else if ((j1 = -k) != 0) {
650                 d *= tens[j1 & 0xf];
651                 for(j = j1 >> 4; (j != 0); j >>= 1, i++)
652                     if ((j & 1) != 0) {
653                         ieps++;
654                         d *= bigtens[i];
655                     }
656             }
657             /* Check that k was computed correctly. */
658             if (k_check && d < 1.0 && ilim > 0) {
659                 if (ilim1 <= 0)
660                     fast_failed = true;
661                 else {
662                     ilim = ilim1;
663                     k--;
664                     d *= 10.;
665                     ieps++;
666                 }
667             }
668             /* eps bounds the cumulative error. */
669 // eps = ieps*d + 7.0;
670
// word0(eps) -= (P-1)*Exp_msk1;
671
eps = ieps*d + 7.0;
672             eps = setWord0(eps, word0(eps) - (P-1)*Exp_msk1);
673             if (ilim == 0) {
674                 S = mhi = null;
675                 d -= 5.0;
676                 if (d > eps) {
677                     buf.append('1');
678                     k++;
679                     return k + 1;
680                 }
681                 if (d < -eps) {
682                     buf.setLength(0);
683                     buf.append('0'); /* copy "0" to buffer */
684                     return 1;
685                 }
686                 fast_failed = true;
687             }
688             if (!fast_failed) {
689                 fast_failed = true;
690                 if (leftright) {
691                     /* Use Steele & White method of only
692                      * generating digits needed.
693                      */

694                     eps = 0.5/tens[ilim-1] - eps;
695                     for(i = 0;;) {
696                         L = (long)d;
697                         d -= L;
698                         buf.append((char)('0' + L));
699                         if (d < eps) {
700                             return k + 1;
701                         }
702                         if (1.0 - d < eps) {
703 // goto bump_up;
704
char lastCh;
705                                 while (true) {
706                                     lastCh = buf.charAt(buf.length() - 1);
707                                     buf.setLength(buf.length() - 1);
708                                     if (lastCh != '9') break;
709                                     if (buf.length() == 0) {
710                                         k++;
711                                         lastCh = '0';
712                                         break;
713                                     }
714                                 }
715                                 buf.append((char)(lastCh + 1));
716                                 return k + 1;
717                         }
718                         if (++i >= ilim)
719                             break;
720                         eps *= 10.0;
721                         d *= 10.0;
722                     }
723                 }
724                 else {
725                     /* Generate ilim digits, then fix them up. */
726                     eps *= tens[ilim-1];
727                     for(i = 1;; i++, d *= 10.0) {
728                         L = (long)d;
729                         d -= L;
730                         buf.append((char)('0' + L));
731                         if (i == ilim) {
732                             if (d > 0.5 + eps) {
733 // goto bump_up;
734
char lastCh;
735                                 while (true) {
736                                     lastCh = buf.charAt(buf.length() - 1);
737                                     buf.setLength(buf.length() - 1);
738                                     if (lastCh != '9') break;
739                                     if (buf.length() == 0) {
740                                         k++;
741                                         lastCh = '0';
742                                         break;
743                                     }
744                                 }
745                                 buf.append((char)(lastCh + 1));
746                                 return k + 1;
747                             }
748                             else
749                                 if (d < 0.5 - eps) {
750                                     while (buf.charAt(buf.length() - 1) == '0')
751                                         buf.setLength(buf.length() - 1);
752 // while(*--s == '0') ;
753
// s++;
754
return k + 1;
755                                 }
756                             break;
757                         }
758                     }
759                 }
760             }
761             if (fast_failed) {
762                 buf.setLength(0);
763                 d = d2;
764                 k = k0;
765                 ilim = ilim0;
766             }
767         }
768
769         /* Do we have a "small" integer? */
770
771         if (be[0] >= 0 && k <= Int_max) {
772             /* Yes. */
773             ds = tens[k];
774             if (ndigits < 0 && ilim <= 0) {
775                 S = mhi = null;
776                 if (ilim < 0 || d < 5*ds || (!biasUp && d == 5*ds)) {
777                     buf.setLength(0);
778                     buf.append('0'); /* copy "0" to buffer */
779                     return 1;
780                 }
781                 buf.append('1');
782                 k++;
783                 return k + 1;
784             }
785             for(i = 1;; i++) {
786                 L = (long) (d / ds);
787                 d -= L*ds;
788                 buf.append((char)('0' + L));
789                 if (i == ilim) {
790                     d += d;
791                     if ((d > ds) || (d == ds && (((L & 1) != 0) || biasUp))) {
792 // bump_up:
793
// while(*--s == '9')
794
// if (s == buf) {
795
// k++;
796
// *s = '0';
797
// break;
798
// }
799
// ++*s++;
800
char lastCh;
801                         while (true) {
802                             lastCh = buf.charAt(buf.length() - 1);
803                             buf.setLength(buf.length() - 1);
804                             if (lastCh != '9') break;
805                             if (buf.length() == 0) {
806                                 k++;
807                                 lastCh = '0';
808                                 break;
809                             }
810                         }
811                         buf.append((char)(lastCh + 1));
812                     }
813                     break;
814                 }
815                 d *= 10.0;
816                 if (d == 0)
817                     break;
818             }
819             return k + 1;
820         }
821
822         m2 = b2;
823         m5 = b5;
824         mhi = mlo = null;
825         if (leftright) {
826             if (mode < 2) {
827                 i = (denorm) ? be[0] + (Bias + (P-1) - 1 + 1) : 1 + P - bbits[0];
828                 /* i is 1 plus the number of trailing zero bits in d's significand. Thus,
829                    (2^m2 * 5^m5) / (2^(s2+i) * 5^s5) = (1/2 lsb of d)/10^k. */

830             }
831             else {
832                 j = ilim - 1;
833                 if (m5 >= j)
834                     m5 -= j;
835                 else {
836                     s5 += j -= m5;
837                     b5 += j;
838                     m5 = 0;
839                 }
840                 if ((i = ilim) < 0) {
841                     m2 -= i;
842                     i = 0;
843                 }
844                 /* (2^m2 * 5^m5) / (2^(s2+i) * 5^s5) = (1/2 * 10^(1-ilim))/10^k. */
845             }
846             b2 += i;
847             s2 += i;
848             mhi = BigInteger.valueOf(1);
849             /* (mhi * 2^m2 * 5^m5) / (2^s2 * 5^s5) = one-half of last printed (when mode >= 2) or
850                input (when mode < 2) significant digit, divided by 10^k. */

851         }
852         /* We still have d/10^k = (b * 2^b2 * 5^b5) / (2^s2 * 5^s5). Reduce common factors in
853            b2, m2, and s2 without changing the equalities. */

854         if (m2 > 0 && s2 > 0) {
855             i = (m2 < s2) ? m2 : s2;
856             b2 -= i;
857             m2 -= i;
858             s2 -= i;
859         }
860
861         /* Fold b5 into b and m5 into mhi. */
862         if (b5 > 0) {
863             if (leftright) {
864                 if (m5 > 0) {
865                     mhi = pow5mult(mhi, m5);
866                     b1 = mhi.multiply(b);
867                     b = b1;
868                 }
869                 if ((j = b5 - m5) != 0)
870                     b = pow5mult(b, j);
871             }
872             else
873                 b = pow5mult(b, b5);
874         }
875         /* Now we have d/10^k = (b * 2^b2) / (2^s2 * 5^s5) and
876            (mhi * 2^m2) / (2^s2 * 5^s5) = one-half of last printed or input significant digit, divided by 10^k. */

877
878         S = BigInteger.valueOf(1);
879         if (s5 > 0)
880             S = pow5mult(S, s5);
881         /* Now we have d/10^k = (b * 2^b2) / (S * 2^s2) and
882            (mhi * 2^m2) / (S * 2^s2) = one-half of last printed or input significant digit, divided by 10^k. */

883
884         /* Check for special case that d is a normalized power of 2. */
885         spec_case = false;
886         if (mode < 2) {
887             if ( (word1(d) == 0) && ((word0(d) & Bndry_mask) == 0)
888                 && ((word0(d) & (Exp_mask & Exp_mask << 1)) != 0)
889                 ) {
890                 /* The special case. Here we want to be within a quarter of the last input
891                    significant digit instead of one half of it when the decimal output string's value is less than d. */

892                 b2 += Log2P;
893                 s2 += Log2P;
894                 spec_case = true;
895             }
896         }
897
898         /* Arrange for convenient computation of quotients:
899          * shift left if necessary so divisor has 4 leading 0 bits.
900          *
901          * Perhaps we should just compute leading 28 bits of S once
902          * and for all and pass them and a shift to quorem, so it
903          * can do shifts and ors to compute the numerator for q.
904          */

905         byte [] S_bytes = S.toByteArray();
906         int S_hiWord = 0;
907         for (int idx = 0; idx < 4; idx++) {
908             S_hiWord = (S_hiWord << 8);
909             if (idx < S_bytes.length)
910                 S_hiWord |= (S_bytes[idx] & 0xFF);
911         }
912         if ((i = (((s5 != 0) ? 32 - hi0bits(S_hiWord) : 1) + s2) & 0x1f) != 0)
913             i = 32 - i;
914         /* i is the number of leading zero bits in the most significant word of S*2^s2. */
915         if (i > 4) {
916             i -= 4;
917             b2 += i;
918             m2 += i;
919             s2 += i;
920         }
921         else if (i < 4) {
922             i += 28;
923             b2 += i;
924             m2 += i;
925             s2 += i;
926         }
927         /* Now S*2^s2 has exactly four leading zero bits in its most significant word. */
928         if (b2 > 0)
929             b = b.shiftLeft(b2);
930         if (s2 > 0)
931             S = S.shiftLeft(s2);
932         /* Now we have d/10^k = b/S and
933            (mhi * 2^m2) / S = maximum acceptable error, divided by 10^k. */

934         if (k_check) {
935             if (b.compareTo(S) < 0) {
936                 k--;
937                 b = b.multiply(BigInteger.valueOf(10)); /* we botched the k estimate */
938                 if (leftright)
939                     mhi = mhi.multiply(BigInteger.valueOf(10));
940                 ilim = ilim1;
941             }
942         }
943         /* At this point 1 <= d/10^k = b/S < 10. */
944
945         if (ilim <= 0 && mode > 2) {
946             /* We're doing fixed-mode output and d is less than the minimum nonzero output in this mode.
947                Output either zero or the minimum nonzero output depending on which is closer to d. */

948             if ((ilim < 0 )
949                     || ((i = b.compareTo(S = S.multiply(BigInteger.valueOf(5)))) < 0)
950                     || ((i == 0 && !biasUp))) {
951             /* Always emit at least one digit. If the number appears to be zero
952                using the current mode, then emit one '0' digit and set decpt to 1. */

953             /*no_digits:
954                 k = -1 - ndigits;
955                 goto ret; */

956                 buf.setLength(0);
957                 buf.append('0'); /* copy "0" to buffer */
958                 return 1;
959 // goto no_digits;
960
}
961 // one_digit:
962
buf.append('1');
963             k++;
964             return k + 1;
965         }
966         if (leftright) {
967             if (m2 > 0)
968                 mhi = mhi.shiftLeft(m2);
969
970             /* Compute mlo -- check for special case
971              * that d is a normalized power of 2.
972              */

973
974             mlo = mhi;
975             if (spec_case) {
976                 mhi = mlo;
977                 mhi = mhi.shiftLeft(Log2P);
978             }
979             /* mlo/S = maximum acceptable error, divided by 10^k, if the output is less than d. */
980             /* mhi/S = maximum acceptable error, divided by 10^k, if the output is greater than d. */
981
982             for(i = 1;;i++) {
983                 BigInteger JavaDoc[] divResult = b.divideAndRemainder(S);
984                 b = divResult[1];
985                 dig = (char)(divResult[0].intValue() + '0');
986                 /* Do we yet have the shortest decimal string
987                  * that will round to d?
988                  */

989                 j = b.compareTo(mlo);
990                 /* j is b/S compared with mlo/S. */
991                 delta = S.subtract(mhi);
992                 j1 = (delta.signum() <= 0) ? 1 : b.compareTo(delta);
993                 /* j1 is b/S compared with 1 - mhi/S. */
994                 if ((j1 == 0) && (mode == 0) && ((word1(d) & 1) == 0)) {
995                     if (dig == '9') {
996                         buf.append('9');
997                         if (roundOff(buf)) {
998                             k++;
999                             buf.append('1');
1000                        }
1001                        return k + 1;
1002// goto round_9_up;
1003
}
1004                    if (j > 0)
1005                        dig++;
1006                    buf.append(dig);
1007                    return k + 1;
1008                }
1009                if ((j < 0)
1010                        || ((j == 0)
1011                            && (mode == 0)
1012                            && ((word1(d) & 1) == 0)
1013                    )) {
1014                    if (j1 > 0) {
1015                        /* Either dig or dig+1 would work here as the least significant decimal digit.
1016                           Use whichever would produce a decimal value closer to d. */

1017                        b = b.shiftLeft(1);
1018                        j1 = b.compareTo(S);
1019                        if (((j1 > 0) || (j1 == 0 && (((dig & 1) == 1) || biasUp)))
1020                            && (dig++ == '9')) {
1021                                buf.append('9');
1022                                if (roundOff(buf)) {
1023                                    k++;
1024                                    buf.append('1');
1025                                }
1026                                return k + 1;
1027// goto round_9_up;
1028
}
1029                    }
1030                    buf.append(dig);
1031                    return k + 1;
1032                }
1033                if (j1 > 0) {
1034                    if (dig == '9') { /* possible if i == 1 */
1035// round_9_up:
1036
// *s++ = '9';
1037
// goto roundoff;
1038
buf.append('9');
1039                        if (roundOff(buf)) {
1040                            k++;
1041                            buf.append('1');
1042                        }
1043                        return k + 1;
1044                    }
1045                    buf.append((char)(dig + 1));
1046                    return k + 1;
1047                }
1048                buf.append(dig);
1049                if (i == ilim)
1050                    break;
1051                b = b.multiply(BigInteger.valueOf(10));
1052                if (mlo == mhi)
1053                    mlo = mhi = mhi.multiply(BigInteger.valueOf(10));
1054                else {
1055                    mlo = mlo.multiply(BigInteger.valueOf(10));
1056                    mhi = mhi.multiply(BigInteger.valueOf(10));
1057                }
1058            }
1059        }
1060        else
1061            for(i = 1;; i++) {
1062// (char)(dig = quorem(b,S) + '0');
1063
BigInteger JavaDoc[] divResult = b.divideAndRemainder(S);
1064                b = divResult[1];
1065                dig = (char)(divResult[0].intValue() + '0');
1066                buf.append(dig);
1067                if (i >= ilim)
1068                    break;
1069                b = b.multiply(BigInteger.valueOf(10));
1070            }
1071
1072        /* Round off last digit */
1073
1074        b = b.shiftLeft(1);
1075        j = b.compareTo(S);
1076        if ((j > 0) || (j == 0 && (((dig & 1) == 1) || biasUp))) {
1077// roundoff:
1078
// while(*--s == '9')
1079
// if (s == buf) {
1080
// k++;
1081
// *s++ = '1';
1082
// goto ret;
1083
// }
1084
// ++*s++;
1085
if (roundOff(buf)) {
1086                k++;
1087                buf.append('1');
1088                return k + 1;
1089            }
1090        }
1091        else {
1092            /* Strip trailing zeros */
1093            while (buf.charAt(buf.length() - 1) == '0')
1094                buf.setLength(buf.length() - 1);
1095// while(*--s == '0') ;
1096
// s++;
1097
}
1098// ret:
1099
// Bfree(S);
1100
// if (mhi) {
1101
// if (mlo && mlo != mhi)
1102
// Bfree(mlo);
1103
// Bfree(mhi);
1104
// }
1105
// ret1:
1106
// Bfree(b);
1107
// JS_ASSERT(s < buf + bufsize);
1108
return k + 1;
1109    }
1110
1111    /* Mapping of JSDToStrMode -> JS_dtoa mode */
1112    private static final int dtoaModes[] = {
1113        0, /* DTOSTR_STANDARD */
1114        0, /* DTOSTR_STANDARD_EXPONENTIAL, */
1115        3, /* DTOSTR_FIXED, */
1116        2, /* DTOSTR_EXPONENTIAL, */
1117        2}; /* DTOSTR_PRECISION */
1118
1119    static void
1120    JS_dtostr(StringBuffer JavaDoc buffer, int mode, int precision, double d)
1121    {
1122        int decPt; /* Position of decimal point relative to first digit returned by JS_dtoa */
1123        boolean[] sign = new boolean[1]; /* true if the sign bit was set in d */
1124        int nDigits; /* Number of significand digits returned by JS_dtoa */
1125
1126// JS_ASSERT(bufferSize >= (size_t)(mode <= DTOSTR_STANDARD_EXPONENTIAL ? DTOSTR_STANDARD_BUFFER_SIZE :
1127
// DTOSTR_VARIABLE_BUFFER_SIZE(precision)));
1128

1129        if (mode == DTOSTR_FIXED && (d >= 1e21 || d <= -1e21))
1130            mode = DTOSTR_STANDARD; /* Change mode here rather than below because the buffer may not be large enough to hold a large integer. */
1131
1132        decPt = JS_dtoa(d, dtoaModes[mode], mode >= DTOSTR_FIXED, precision, sign, buffer);
1133        nDigits = buffer.length();
1134
1135        /* If Infinity, -Infinity, or NaN, return the string regardless of the mode. */
1136        if (decPt != 9999) {
1137            boolean exponentialNotation = false;
1138            int minNDigits = 0; /* Minimum number of significand digits required by mode and precision */
1139            int p;
1140            int q;
1141
1142            switch (mode) {
1143                case DTOSTR_STANDARD:
1144                    if (decPt < -5 || decPt > 21)
1145                        exponentialNotation = true;
1146                    else
1147                        minNDigits = decPt;
1148                    break;
1149
1150                case DTOSTR_FIXED:
1151                    if (precision >= 0)
1152                        minNDigits = decPt + precision;
1153                    else
1154                        minNDigits = decPt;
1155                    break;
1156
1157                case DTOSTR_EXPONENTIAL:
1158// JS_ASSERT(precision > 0);
1159
minNDigits = precision;
1160                    /* Fall through */
1161                case DTOSTR_STANDARD_EXPONENTIAL:
1162                    exponentialNotation = true;
1163                    break;
1164
1165                case DTOSTR_PRECISION:
1166// JS_ASSERT(precision > 0);
1167
minNDigits = precision;
1168                    if (decPt < -5 || decPt > precision)
1169                        exponentialNotation = true;
1170                    break;
1171            }
1172
1173            /* If the number has fewer than minNDigits, pad it with zeros at the end */
1174            if (nDigits < minNDigits) {
1175                p = minNDigits;
1176                nDigits = minNDigits;
1177                do {
1178                    buffer.append('0');
1179                } while (buffer.length() != p);
1180            }
1181
1182            if (exponentialNotation) {
1183                /* Insert a decimal point if more than one significand digit */
1184                if (nDigits != 1) {
1185                    buffer.insert(1, '.');
1186                }
1187                buffer.append('e');
1188                if ((decPt - 1) >= 0)
1189                    buffer.append('+');
1190                buffer.append(decPt - 1);
1191// JS_snprintf(numEnd, bufferSize - (numEnd - buffer), "e%+d", decPt-1);
1192
} else if (decPt != nDigits) {
1193                /* Some kind of a fraction in fixed notation */
1194// JS_ASSERT(decPt <= nDigits);
1195
if (decPt > 0) {
1196                    /* dd...dd . dd...dd */
1197                    buffer.insert(decPt, '.');
1198                } else {
1199                    /* 0 . 00...00dd...dd */
1200                    for (int i = 0; i < 1 - decPt; i++)
1201                        buffer.insert(0, '0');
1202                    buffer.insert(1, '.');
1203                }
1204            }
1205        }
1206
1207        /* If negative and neither -0.0 nor NaN, output a leading '-'. */
1208        if (sign[0] &&
1209                !(word0(d) == Sign_bit && word1(d) == 0) &&
1210                !((word0(d) & Exp_mask) == Exp_mask &&
1211                  ((word1(d) != 0) || ((word0(d) & Frac_mask) != 0)))) {
1212            buffer.insert(0, '-');
1213        }
1214    }
1215
1216}
1217
Popular Tags