001 /*
002  *  JScripter Emulation 1.0 - To Script Java
003  *  Copyright (C) 2008-2011  J.J.Liu<jianjunliu@126.com> <http://www.jscripter.org>
004  *  
005  *  This program is free software: you can redistribute it and/or modify
006  *  it under the terms of the GNU Affero General Public License as published by
007  *  the Free Software Foundation, either version 3 of the License, or
008  *  (at your option) any later version.
009  *  
010  *  This program is distributed in the hope that it will be useful,
011  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
012  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
013  *  GNU Affero General Public License for more details.
014  *  
015  *  You should have received a copy of the GNU Affero General Public License
016  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
017  */
018 
019 package org.jscripter.emu.java.lang;
020 
021 import js.Js;
022 
023 /**
024  * <p><b>Internally</b> represents primitive double values, emulating a standard
025  * <tt>java.lang</tt> interface or class with the same simple name as this one.</p>
026  * <p>This interface or class is only used internally by JS re-compiler implementations.</p>
027  * <p>Please refer to <a href="http://java.sun.com/docs/">the Java API Standards</a> for detail description of the original class or interface.</p>
028  * 
029  * @author <a href="mailto:jianjunliu@126.com">J.J.Liu (Jianjun Liu)</a> at <a href="http://www.jscripter.org" target="_blank">http://www.jscripter.org</a>
030  * 
031  * @javascript Re-compilers must redirect the resolution of the emulated original Java class or interface to this one.
032  */
033 public final class Double extends Number implements Comparable<Double>
034 {
035     /**
036      * <p>Internally stores a constant holding the largest positive finite value of
037      * type double, (2-2<sup>-52</sup>)ยท2<sup>1023</sup>.</p>
038      * <p>It is equal to the hexadecimal floating-point literal <tt>0x1.fffffffffffffP+1023</tt> and 
039      * also equal to <tt>Double.longBitsToDouble(0x7fefffffffffffffL)</tt>.</p>
040      * @since 1.0
041      * @javascript Re-compilers must report error on end-users directly using this field.
042      */
043     public static final double MAX_VALUE = 1.7976931348623157e+308;
044     /**
045      * <p>Internally stores a constant holding the smallest positive normal value of type double, 2<sup>-1022</sup>.</p>
046      * <p>It is equal to the hexadecimal floating-point literal <tt>0x1.0P-1022</tt> and also equal to
047      * <tt>Double.longBitsToDouble(0x1L)</tt>.</p>
048      * @since 1.0
049      * @javascript Re-compilers must report error on end-users directly using this field.
050      */
051     public static final double MIN_NORMAL = 2.2250738585072014e-308;
052     /**
053      * <p>Internally stores a constant holding the smallest positive nonzero value
054      * of type double, 2<sup>-1074</sup>.</p>
055      * <p>It is equal to the hexadecimal floating-point literal <tt>0x0.0000000000001P-1022</tt> and 
056      * also equal to <tt>Double.longBitsToDouble(0x7fefffffffffffffL)</tt>.</p>
057      * @since 1.0
058      * @javascript Re-compilers must report error on end-users directly using this field.
059      */
060     public static final double MIN_VALUE = 4.9e-324;
061     /**
062      * <p>Internally stores the maximum exponent a finite double variable may have.</p>
063      * @since 1.0
064      * @javascript Re-compilers must report error on end-users directly using this field.
065      */
066     public static final int MAX_EXPONENT = 1023;
067     /**
068      * <p>Internally stores the minimum exponent a normalized double variable may have.</p>
069      * @since 1.0
070      * @javascript Re-compilers must report error on end-users directly using this field.
071      */
072     public static final int MIN_EXPONENT = -1022;
073     /**
074      * <p>Internally stores constant holding a Not-a-Number (NaN) value of type double.</p>
075      * <p>It is equivalent to the value returned by <tt>Double.longBitsToDouble(0x7fefffffffffffffL)</tt>.</p>
076      * @since 1.0
077      * @javascript Re-compilers must report error on end-users directly using this field.
078      */
079     public static final double NaN = 0d / 0d;
080     /**
081      * <p>Internally stores constant holding the negative infinity of type double.</p>
082      * <p>It is equivalent to the value returned by <tt>Double.longBitsToDouble(0xfff0000000000000L)</tt>.</p>
083      * @since 1.0
084      * @javascript Re-compilers must report error on end-users directly using this
085      *          field.
086      */
087     public static final double NEGATIVE_INFINITY = -1d / 0d;
088     /**
089      * <p>Internally stores constant holding the positive infinity of type double.</p>
090      * <p>It is equivalent to the value returned by <tt>Double.longBitsToDouble(0x7ff0000000000000L)</tt>.</p>
091      * @since 1.0
092      * @javascript Re-compilers must report error on end-users directly using this field.
093      */
094     public static final double POSITIVE_INFINITY = 1d / 0d;
095     /**
096      * <p>Internally stores the number of bits used to represent a double value.</p>
097      * @since 1.0
098      * @javascript Re-compilers must report error on end-users directly using this field.
099      */
100     public static final int SIZE = 64;
101 
102     /**
103      * <p>Compares the two specified floating-point numbers.</p>
104      * @param x A floating-point number.
105      * @param y A floating-point number.
106      * @return the value 0 if <tt>x</tt> is numerically equal to <tt>y</tt>; a value less than 0 if 
107      * <tt>x</tt> is numerically less than <tt>y</tt>; and a value greater than 0 if <tt>x</tt> is
108      * numerically greater than <tt>y</tt>.
109      * @since 1.0
110      * @javascript Re-compilers must report error on end-users directly using this method.
111      */
112     public static final int compare(double x, double y) {
113         return ((java.lang.Integer) Js.cond(Js.lt(x, y), -1,
114                 Js.cond(Js.gt(x, y), 1, 0))).intValue();
115     }
116 
117     /**
118      * <p>Determines whether the specified number is infinitely large in magnitude.</p>
119      * @param x A floating-point number to be tested.
120      * @return <tt>true</tt> if the argument is positive infinity or negative infinity; <tt>false</tt> otherwise.
121      * @since 1.0
122      * @javascript Re-compilers must report error on end-users directly using this method. 
123      * As a "synchronized" static emulating method, its invocation should be re-compiled into in-lined code for efficiency.
124      */
125     public static final synchronized boolean isInfinite(double x) {
126         return Js.not(Js.core().isFinite(x));
127     }
128 
129     /**
130      * <p>Determines whether the specified number is a Not-a-Number (NaN) value.</p>
131      * @param x A floating-point number to be tested.
132      * @return <tt>true</tt> if the argument is NaN; <tt>false</tt> otherwise.
133      * @since 1.0
134      * @javascript Re-compilers must report error on end-users directly using this method.
135      * As a "synchronized" static emulating method, its invocation should be re-compiled into in-lined code for efficiency.
136      */
137     public static final synchronized boolean isNaN(double x) {
138         return Js.core().isNaN(x);
139     }
140 
141     /**
142      * <p>Returns a new double initialized to the value represented by the specified string.</p>
143      * @param s A string to be parsed.
144      * @return The double value represented by the string argument.
145      * @throws java.lang.NumberFormatException if the string does not contain a parsable double.
146      * @since 1.0
147      * @javascript Re-compilers must report error on end-users directly using this method.
148      */
149     public static final synchronized double parseDouble(java.lang.String s)
150             throws java.lang.NumberFormatException {
151         try {
152             return Js.parseFloat(s);
153         } catch (java.lang.Exception e) {
154             throw new java.lang.NumberFormatException(e.toString());
155         }
156     }
157 
158     /**
159      * <p>Returns a string representation of the specified floating-point number.</p>
160      * @param d A floating-point number to be converted.
161      * @return A string representation of the argument.
162      * @since 1.0
163      * @javascript Re-compilers must report error on end-users directly using this method.
164      * As a "synchronized" static emulating method, its invocation should be re-compiled into in-lined code for efficiency.
165      */
166     public static final synchronized java.lang.String toString(double d) {
167         return String.valueOf(d);
168     }
169 
170     /**
171      * <p>Returns a {@link Double} representing the specified floating-point value.</p>
172      * @param d A floating-point value.
173      * @return A {@link Double} representing <tt>d</tt>.
174      * @since 1.0
175      * @javascript Re-compilers must report error on end-users directly using this method.
176      * As a "synchronized" static emulating method, its invocation should be re-compiled into in-lined code for efficiency.
177      */
178     public static final synchronized Double valueOf(double d) {
179         return new Double(d);
180     }
181 
182     /**
183      * <p>Returns a {@link Double} represented by the specified string value.</p>
184      * @param s A string value.
185      * @return A {@link Double} represented by <tt>s</tt>.
186      * @throws java.lang.NumberFormatException if the string does not contain a parsable float.
187      * @since 1.0
188      * @javascript Re-compilers must report error on end-users directly using this method.
189      * As a "synchronized" static emulating method, its invocation should be re-compiled into in-lined code for efficiency.
190      */
191     public static final synchronized Double valueOf(java.lang.String s)
192             throws java.lang.NumberFormatException {
193         return new Double(parseDouble(s));
194     }
195 
196     /**
197      * <p>Allocates an {@link Double} representing the double argument.</p>
198      * @param value A double value.
199      * @since 1.0
200      * @javascript Re-compilers must report error on end-users directly using this constructor. 
201      * A re-compiler simply replaces an invocation of this constructor with its argument.
202      */
203     public Double(double value) {
204     }
205 
206     /**
207      * <p>Allocates a {@link Double} representing the value indicated by the string parameter.</p>
208      * <p>The string is converted to a long value in exactly the manner used by the
209      * {@link #parseDouble(String)} method for radix 10.</p>
210      * @param s A string to be converted to a {@link Double}.
211      * @throws NumberFormatException if the string does not contain a parsable double.
212      * @since 1.0
213      * @javascript Re-compilers must report error on end-users directly using this constructor. 
214      * A re-compiler simply replaces an invocation of this constructor with an invocation of 
215      * {@link #valueOf(String)} passing the string argument.
216      */
217     public Double(java.lang.String s) {
218     }
219 
220     /**
221      * <p>Returns the value of this {@link Double} as a byte primitive.</p>
222      * @return The primitive byte value.
223      * @since 1.0
224      * @javascript Re-compilers must report error on end-users directly using this method. 
225      * A re-compiler simply replaces an invocation of this native method with the current {@link Double} 
226      * involving rounding or truncation necessarily.
227      */
228     @Override
229     public final native byte byteValue();
230 
231     /**
232      * <p>Returns the value of this {@link Double} as a short primitive.</p>
233      * @return The primitive short value.
234      * @since 1.0
235      * @javascript Re-compilers must report error on end-users directly using this method. 
236      * A re-compiler simply replaces an invocation of this native method with the current {@link Double} 
237      * involving rounding or truncation necessarily.
238      */
239     @Override
240     public final native short shortValue();
241 
242     /**
243      * <p>Returns the value of this {@link Double} as an int primitive.</p>
244      * @return The primitive int value.
245      * @since 1.0
246      * @javascript Re-compilers must report error on end-users directly using this method. 
247      * A re-compiler simply replaces an invocation of this native method with the current {@link Double} 
248      * involving rounding or truncation necessarily.
249      */
250     @Override
251     public final native int intValue();
252 
253     /**
254      * <p>Returns the value of this {@link Double} as a long primitive.</p>
255      * @return The primitive long value.
256      * @since 1.0
257      * @javascript Re-compilers must report error on end-users directly using this method. 
258      * A re-compiler simply replaces an invocation of this native method with the current {@link Double} 
259      * involving rounding or truncation necessarily.
260      */
261     @Override
262     public final native long longValue();
263 
264     /**
265      * <p>Returns the value of this {@link Double} as a float primitive.</p>
266      * @return The primitive float value.
267      * @since 1.0
268      * @javascript Re-compilers must report error on end-users directly using this method. 
269      * A re-compiler simply replaces an invocation of this native method with the current {@link Double} 
270      * involving rounding necessarily.
271      */
272     @Override
273     public final native float floatValue();
274 
275     /**
276      * <p>Returns the value of this {@link Double} as a double primitive.</p>
277      * @return The primitive double value.
278      * @since 1.0
279      * @javascript Re-compilers must report error on end-users directly using this method. 
280      * A re-compiler simply replaces an invocation of this native method with the current {@link Double}.
281      */
282     @Override
283     public final native double doubleValue();
284 
285     /**
286      * <p>Compares two {@link Double}s numerically.</p>
287      * @param d The {@link Double} to be compared.
288      * @return 0 if this {@link Double} is equal to the argument {@link Double}; a value less than 0 
289      * if this {@link Double} is numerically less than the argument {@link Double}; and a value 
290      * greater than 0 if this {@link Double} is numerically greater than the argument {@link Double}.
291      * @since 1.0
292      * @javascript Re-compilers must report error on end-users directly using this method. 
293      * For efficiency, the invocation of this instance emulation method with single statement can be in-lined in re-compilation.
294      */
295     public final int compareTo(Double d) {
296         return ((java.lang.Integer) Js.cond(Js.lt(this, d), -1,
297                 Js.cond(Js.gt(this, d), 1, 0))).intValue();
298     }
299 
300     /**
301      * <p>Compares this {@link Double} to the specified object.</p>
302      * <p>Returns <tt>true</tt> if and only if the argument is not <tt>null</tt> and is a {@link Double} 
303      * that represents the same value as this {@link Double}.</p>
304      * @param o The object to compare with.
305      * @return <tt>true</tt> if the {@link Double}s represent the same value; <tt>false</tt> otherwise.
306      * @since 1.0
307      * @javascript Re-compilers must report error on end-users directly using this method.
308      * For efficiency, the invocation of this instance emulation method with single statement can be in-lined in re-compilation.
309      */
310     @Override
311     public final boolean equals(java.lang.Object o) {
312         return Js.eqs(this, o);
313     }
314 
315     /**
316      * <p>Returns a hash code for this {@link Double}.</p>
317      * @return A hash code value for this {@link Double}.
318      * @since 1.0
319      * @javascript Re-compilers must report error on end-users directly using this method.
320      * For efficiency, the invocation of this instance emulation method with single statement can be in-lined in re-compilation.
321      */
322     @Override
323     public final int hashCode() {
324         return intValue();
325     }
326 
327     /**
328      * <p>Determines whether this {@link Double} is infinitely large in magnitude.</p>
329      * @return <tt>true</tt> if this {@link Double} is positive infinity or negative infinity; 
330      * <tt>false</tt> otherwise.
331      * @since 1.0
332      * @javascript Re-compilers must report error on end-users directly using this method.
333      * For efficiency, the invocation of this instance emulation method with single statement can be in-lined in re-compilation.
334      */
335     public final synchronized boolean isInfinite() {
336         return isInfinite(doubleValue());
337     }
338 
339     /**
340      * <p>Determines whether {@link Double} is a Not-a-Number (NaN) value.</p>
341      * @return <tt>true</tt> if {@link Double} is NaN; <tt>false</tt> otherwise.
342      * @since 1.0
343      * @javascript Re-compilers must report error on end-users directly using this method.
344      * For efficiency, the invocation of this instance emulation method with single statement can be in-lined in re-compilation.
345      */
346     public final synchronized boolean isNaN() {
347         return isNaN(doubleValue());
348     }
349 
350     /**
351      * <p>Returns a string representing this {@link Double}'s value.</p>
352      * <p>The value is converted to signed decimal representation and returned as a string, exactly 
353      * as if the double value were given as an argument to the {@link #toString(double)} method.</p>
354      * @return A string representation of this {@link Double}.
355      * @since 1.0
356      * @javascript Re-compilers must report error on end-users directly using this method.
357      */
358     @Override
359     public final java.lang.String toString() {
360         return toString(doubleValue());
361     }
362 
363     private static final double MANTISSA = Math.pow(2, 52);
364 
365     /**
366      * <p>Returns the floating-point value corresponding to a given bit representation.</p>
367      * <p>The argument is considered to be a representation of a floating-point value according to 
368      * the IEEE 754 floating-point "single format" bit layout.</p>
369      * @param bits A representation of a floating-point value according to the IEEE 754 floating-point 
370      * "double format" bit layout.
371      * @return The floating-point value with the same bit pattern.
372      * @since 1.0
373      * @javascript Re-compilers must report error on end-users directly using this method.
374      */
375     public final static double longBitsToDouble(long bits) {
376         int e = ((int) Js.lshr(bits, 52)) & 0x7ff;
377         int d = e == 0 ? 1 : 0;
378         e = e - 1023 + d;
379         long m = mantissa(bits);
380         int s = Js.lshr(bits, 63) == 0L ? 1 : -1;
381         if (e == 1024) {
382             if (m != 0) {
383                 return Double.NaN;
384             } else {
385                 return s < 0 ? Double.NEGATIVE_INFINITY
386                         : Double.POSITIVE_INFINITY;
387             }
388         }
389         return s * ((m / MANTISSA + 1 - d) * Math.pow(2, e));
390     }
391 
392     private static long mantissa(long bits) {
393         return Js.land(bits, 0xfffffffffffffL);
394     }
395 
396     /**
397      * <p>Returns a representation of the specified floating-point value according to the IEEE 754 
398      * floating-point "double format" bit layout.</p>
399      * @param value A floating-point number.
400      * @return The bits that represent the floating-point number.
401      * @since 1.0
402      * @javascript Re-compilers must report error on end-users directly using this method.
403      */
404     public final static long doubleToLongBits(double value) {
405         long result = doubleToRawLongBits(value);
406         // Check for NaN based on values of bit fields, maximum
407         // exponent and nonzero significand.
408         if (Js.leq(Js.land(result, 0x7ff0000000000000L), 0x7ff0000000000000L)
409                 && Js.leq(Js.land(result, 0x000fffffffffffffL), 0L))
410             result = 0x7ff8000000000000L;
411         return result;
412     }
413 
414     /**
415      * <p>Returns a representation of the specified floating-point value according to the IEEE 754 
416      * floating-point "double format" bit layout, preserving Not-a-Number (NaN) values.</p>
417      * @param value A floating-point number.
418      * @return The bits that represent the floating-point number.
419      * @since 1.0
420      * @javascript Re-compilers must report error on end-users directly using this method.
421      */
422     public final static long doubleToRawLongBits(double value) {
423         if (value == POSITIVE_INFINITY)
424             return 0x7ff0000000000000L;
425         if (value == NEGATIVE_INFINITY)
426             return 0xfff0000000000000L;
427         long s = Js.cond(value < 0, 1L, 0L).longValue();
428         value = Math.abs(value);
429         long e = (long) (jsx.core.Maths.log2(value) + 1023);
430         long m = (long) (value / Math.pow(2, e - 1075));
431         if (e == 0L) {
432             m = Js.lshru(m, 1);
433         } else {
434             m = mantissa(m);
435         }
436         return m | Js.lshl(e, 52) | Js.lshl(s, 63);
437     }
438 }