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