KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > es > ESNumber


1 /*
2  * Copyright (c) 1998-2006 Caucho Technology -- all rights reserved
3  *
4  * This file is part of Resin(R) Open Source
5  *
6  * Each copy or derived work must preserve the copyright notice and this
7  * notice unmodified.
8  *
9  * Resin Open Source is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * Resin Open Source is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
17  * of NON-INFRINGEMENT. See the GNU General Public License for more
18  * details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with Resin Open Source; if not, write to the
22  * Free SoftwareFoundation, Inc.
23  * 59 Temple Place, Suite 330
24  * Boston, MA 02111-1307 USA
25  *
26  * @author Scott Ferguson
27  */

28
29 package com.caucho.es;
30
31 import com.caucho.vfs.VfsWriteObject;
32 import com.caucho.vfs.WriteStream;
33
34 import java.io.Externalizable JavaDoc;
35 import java.io.IOException JavaDoc;
36 import java.io.ObjectInput JavaDoc;
37 import java.io.ObjectOutput JavaDoc;
38
39 /**
40  * Implementation class for JavaScript numbers. Essentially, these are
41  * equivalent to Java doubles.
42  */

43 public class ESNumber extends ESBase implements VfsWriteObject, Externalizable JavaDoc {
44   public static ESNumber ZERO = new ESNumber(0.0);
45   public static ESNumber ONE = new ESNumber(1.0);
46   public static ESNumber NaN = new ESNumber(0.0/0.0);
47   static ESNumber ints[];
48   static {
49     ints = new ESNumber[128];
50     for (int i = 0; i < ints.length; i++)
51       ints[i] = new ESNumber(i);
52   }
53
54   private double value;
55
56   /**
57    * Null-arg constructor for serialization.
58    */

59   public ESNumber()
60   {
61     prototype = esNull;
62   }
63
64   /**
65    * Create a new object based on a prototype
66    */

67   private ESNumber(double value)
68   {
69     prototype = esNull;
70     this.value = value;
71   }
72
73   public static ESNumber create(double value)
74   {
75     try {
76       // Can't use 0 because of -0
77
if (value >= 128 || value <= 0)
78     return new ESNumber(value);
79     
80       int intValue = (int) value;
81       if (intValue == value)
82     return ints[intValue];
83       else
84     return new ESNumber(value);
85     } catch (Exception JavaDoc e) {
86       return new ESNumber(value);
87     }
88   }
89
90   /**
91    * Any non-zero number is true.
92    *
93    * XXX: NaN and inf?
94    */

95   public boolean toBoolean()
96   {
97     return ! Double.isNaN(value) && value != 0.0;
98   }
99
100   public boolean isNum()
101   {
102     return true;
103   }
104
105   public double toNum()
106   {
107     return value;
108   }
109
110   public ESObject toObject() throws ESException
111   {
112     return new ESWrapper("Number", Global.getGlobalProto().numProto, this);
113   }
114
115   public Object JavaDoc toJavaObject()
116   {
117     return new Double JavaDoc(value);
118   }
119
120   public ESBase typeof() throws ESException
121   {
122     return ESString.create("number");
123   }
124
125   public Class JavaDoc getJavaType()
126   {
127     if ((int) value == value)
128       return int.class;
129     else
130       return double.class;
131   }
132
133   public ESBase getProperty(ESString key) throws Throwable JavaDoc
134   {
135     return Global.getGlobalProto().numProto.getProperty(key);
136   }
137
138   public ESString toStr()
139   {
140     int intValue = (int) value;
141
142     if (intValue == value)
143       return ESString.create(intValue);
144     else
145       return ESString.create(toString());
146   }
147   
148   /**
149    * Returns the string representation of the number.
150    *
151    * Notes: the spec says
152    * 1) -0 should be printed at 0.
153    * 2) 20 decimal digit integers should be printed as integers.
154    * This is insane since the double can only almost a 16 digit decimal.
155    * 3) The exponent should be lower case.
156    */

157   public String JavaDoc toString()
158   {
159     int intValue = (int) value;
160
161     if (intValue == value)
162       return String.valueOf(intValue);
163     else if ((long) value == value)
164       return String.valueOf((long) value);
165     else if (Double.isNaN(value))
166       return "NaN";
167     else if (Double.isInfinite(value))
168       return (value < 0 ? "-Infinity" : "Infinity");
169
170     return String.valueOf(value).toLowerCase();
171   }
172
173   public void print(WriteStream os) throws IOException JavaDoc
174   {
175     int intValue = (int) value;
176
177     if (intValue == value)
178       os.print(intValue);
179     else if ((long) value == value)
180       os.print((long) value);
181     else if (Double.isNaN(value))
182       os.print("NaN");
183     else if (Double.isInfinite(value))
184       os.print(value < 0 ? "-Infinity" : "Infinity");
185     else
186       os.print(value);
187   }
188
189   public int hashCode()
190   {
191     long bits = Double.doubleToLongBits(value);
192
193     return (int) bits + 65517 * (int) (bits >> 32);
194   }
195
196   public boolean equals(Object JavaDoc b)
197   {
198     return (b instanceof ESNumber) && value == ((ESNumber) b).value;
199   }
200
201   public boolean ecmaEquals(ESBase b) throws Throwable JavaDoc
202   {
203     return b != esNull && value == b.toNum();
204   }
205
206   public boolean lessThan(ESBase b, boolean neg) throws Throwable JavaDoc
207   {
208     double db = b.toNum();
209
210     if (Double.isNaN(value) || Double.isNaN(db))
211       return false;
212     else
213       return (value < db) != neg;
214   }
215
216   public ESBase plus(ESBase b) throws Throwable JavaDoc
217   {
218     if (b instanceof ESNumber)
219       return create(value + ((ESNumber) b).value);
220     else {
221       ESBase primB = b.toPrimitive(NONE);
222
223       if (primB instanceof ESString)
224     return ESString.create(toString() + primB.toString());
225       else
226     return create(value + primB.toNum());
227     }
228   }
229
230   /**
231    * Save the external representation.
232    */

233   public void writeExternal(ObjectOutput JavaDoc os)
234     throws IOException JavaDoc
235   {
236     os.writeDouble(value);
237   }
238
239   /**
240    * Restore the external representation.
241    */

242   public void readExternal(ObjectInput JavaDoc is)
243     throws IOException JavaDoc
244   {
245     value = is.readDouble();
246   }
247 }
248
Popular Tags