1/*
2 *  Licensed to the Apache Software Foundation (ASF) under one or more
3 *  contributor license agreements.  See the NOTICE file distributed with
4 *  this work for additional information regarding copyright ownership.
5 *  The ASF licenses this file to You under the Apache License, Version 2.0
6 *  (the "License"); you may not use this file except in compliance with
7 *  the License.  You may obtain a copy of the License at
8 *
9 *     http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *  Unless required by applicable law or agreed to in writing, software
12 *  distributed under the License is distributed on an "AS IS" BASIS,
13 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *  See the License for the specific language governing permissions and
15 *  limitations under the License.
16 */
17
18package java.lang;
19
20/**
21 * The wrapper for the primitive type {@code float}.
22 *
23 * @see java.lang.Number
24 * @since 1.0
25 */
26public final class Float extends Number implements Comparable<Float> {
27    static final int EXPONENT_BIAS = 127;
28
29    static final int EXPONENT_BITS = 9;
30    static final int MANTISSA_BITS = 23;
31    static final int NON_MANTISSA_BITS = 9;
32
33    static final int SIGN_MASK     = 0x80000000;
34    static final int EXPONENT_MASK = 0x7f800000;
35    static final int MANTISSA_MASK = 0x007fffff;
36
37    private static final long serialVersionUID = -2671257302660747028L;
38
39    /**
40     * The value which the receiver represents.
41     */
42    private final float value;
43
44    /**
45     * Constant for the maximum {@code float} value, (2 - 2<sup>-23</sup>) * 2<sup>127</sup>.
46     */
47    public static final float MAX_VALUE = 3.40282346638528860e+38f;
48
49    /**
50     * Constant for the minimum {@code float} value, 2<sup>-149</sup>.
51     */
52    public static final float MIN_VALUE = 1.40129846432481707e-45f;
53
54    /**
55     * Constant for the Not-a-Number (NaN) value of the {@code float} type.
56     */
57    public static final float NaN = 0.0f / 0.0f;
58
59    /**
60     * Constant for the positive infinity value of the {@code float} type.
61     */
62    public static final float POSITIVE_INFINITY = 1.0f / 0.0f;
63
64    /**
65     * Constant for the negative infinity value of the {@code float} type.
66     */
67    public static final float NEGATIVE_INFINITY = -1.0f / 0.0f;
68
69    /**
70     * Constant for the smallest positive normal value of the {@code float} type.
71     *
72     * @since 1.6
73     */
74    public static final float MIN_NORMAL = 1.1754943508222875E-38f;
75
76    /**
77     * Maximum base-2 exponent that a finite value of the {@code float} type may have.
78     * Equal to {@code Math.getExponent(Float.MAX_VALUE)}.
79     *
80     * @since 1.6
81     */
82    public static final int MAX_EXPONENT = 127;
83
84    /**
85     * Minimum base-2 exponent that a normal value of the {@code float} type may have.
86     * Equal to {@code Math.getExponent(Float.MIN_NORMAL)}.
87     *
88     * @since 1.6
89     */
90    public static final int MIN_EXPONENT = -126;
91
92    /**
93     * The {@link Class} object that represents the primitive type {@code
94     * float}.
95     *
96     * @since 1.1
97     */
98    @SuppressWarnings("unchecked")
99    public static final Class<Float> TYPE
100            = (Class<Float>) float[].class.getComponentType();
101    // Note: Float.TYPE can't be set to "float.class", since *that* is
102    // defined to be "java.lang.Float.TYPE";
103
104    /**
105     * Constant for the number of bits needed to represent a {@code float} in
106     * two's complement form.
107     *
108     * @since 1.5
109     */
110    public static final int SIZE = 32;
111
112    /**
113     * Constructs a new {@code Float} with the specified primitive float value.
114     *
115     * @param value
116     *            the primitive float value to store in the new instance.
117     */
118    public Float(float value) {
119        this.value = value;
120    }
121
122    /**
123     * Constructs a new {@code Float} with the specified primitive double value.
124     *
125     * @param value
126     *            the primitive double value to store in the new instance.
127     */
128    public Float(double value) {
129        this.value = (float) value;
130    }
131
132    /**
133     * Constructs a new {@code Float} from the specified string.
134     *
135     * @param string
136     *            the string representation of a float value.
137     * @throws NumberFormatException
138     *             if {@code string} can not be parsed as a float value.
139     * @see #parseFloat(String)
140     */
141    public Float(String string) throws NumberFormatException {
142        this(parseFloat(string));
143    }
144
145    /**
146     * Compares this object to the specified float object to determine their
147     * relative order. There are two special cases:
148     * <ul>
149     * <li>{@code Float.NaN} is equal to {@code Float.NaN} and it is greater
150     * than any other float value, including {@code Float.POSITIVE_INFINITY};</li>
151     * <li>+0.0f is greater than -0.0f</li>
152     * </ul>
153     *
154     * @param object
155     *            the float object to compare this object to.
156     * @return a negative value if the value of this float is less than the
157     *         value of {@code object}; 0 if the value of this float and the
158     *         value of {@code object} are equal; a positive value if the value
159     *         of this float is greater than the value of {@code object}.
160     * @see java.lang.Comparable
161     * @since 1.2
162     */
163    public int compareTo(Float object) {
164        return compare(value, object.value);
165    }
166
167    @Override
168    public byte byteValue() {
169        return (byte) value;
170    }
171
172    @Override
173    public double doubleValue() {
174        return value;
175    }
176
177    /**
178     * Tests this double for equality with {@code object}.
179     * To be equal, {@code object} must be an instance of {@code Float} and
180     * {@code floatToIntBits} must give the same value for both objects.
181     *
182     * <p>Note that, unlike {@code ==}, {@code -0.0} and {@code +0.0} compare
183     * unequal, and {@code NaN}s compare equal by this method.
184     *
185     * @param object
186     *            the object to compare this float with.
187     * @return {@code true} if the specified object is equal to this
188     *         {@code Float}; {@code false} otherwise.
189     */
190    @Override
191    public boolean equals(Object object) {
192        return (object instanceof Float) &&
193                (floatToIntBits(this.value) == floatToIntBits(((Float) object).value));
194    }
195
196    /**
197     * Returns an integer corresponding to the bits of the given
198     * <a href="http://en.wikipedia.org/wiki/IEEE_754-1985">IEEE 754</a> single precision
199     * float {@code value}. All <em>Not-a-Number (NaN)</em> values are converted to a single NaN
200     * representation ({@code 0x7fc00000}) (compare to {@link #floatToRawIntBits}).
201     */
202    public static native int floatToIntBits(float value);
203
204    /**
205     * Returns an integer corresponding to the bits of the given
206     * <a href="http://en.wikipedia.org/wiki/IEEE_754-1985">IEEE 754</a> single precision
207     * float {@code value}. <em>Not-a-Number (NaN)</em> values are preserved (compare
208     * to {@link #floatToIntBits}).
209     */
210    public static native int floatToRawIntBits(float value);
211
212    /**
213     * Gets the primitive value of this float.
214     *
215     * @return this object's primitive value.
216     */
217    @Override
218    public float floatValue() {
219        return value;
220    }
221
222    @Override
223    public int hashCode() {
224        return floatToIntBits(value);
225    }
226
227    /**
228     * Returns the <a href="http://en.wikipedia.org/wiki/IEEE_754-1985">IEEE 754</a>
229     * single precision float corresponding to the given {@code bits}.
230     */
231    public static native float intBitsToFloat(int bits);
232
233    @Override
234    public int intValue() {
235        return (int) value;
236    }
237
238    /**
239     * Indicates whether this object represents an infinite value.
240     *
241     * @return {@code true} if the value of this float is positive or negative
242     *         infinity; {@code false} otherwise.
243     */
244    public boolean isInfinite() {
245        return isInfinite(value);
246    }
247
248    /**
249     * Indicates whether the specified float represents an infinite value.
250     *
251     * @param f
252     *            the float to check.
253     * @return {@code true} if the value of {@code f} is positive or negative
254     *         infinity; {@code false} otherwise.
255     */
256    public static boolean isInfinite(float f) {
257        return (f == POSITIVE_INFINITY) || (f == NEGATIVE_INFINITY);
258    }
259
260    /**
261     * Indicates whether this object is a <em>Not-a-Number (NaN)</em> value.
262     *
263     * @return {@code true} if this float is <em>Not-a-Number</em>;
264     *         {@code false} if it is a (potentially infinite) float number.
265     */
266    public boolean isNaN() {
267        return isNaN(value);
268    }
269
270    /**
271     * Indicates whether the specified float is a <em>Not-a-Number (NaN)</em>
272     * value.
273     *
274     * @param f
275     *            the float value to check.
276     * @return {@code true} if {@code f} is <em>Not-a-Number</em>;
277     *         {@code false} if it is a (potentially infinite) float number.
278     */
279    public static boolean isNaN(float f) {
280        return f != f;
281    }
282
283    @Override
284    public long longValue() {
285        return (long) value;
286    }
287
288    /**
289     * Parses the specified string as a float value.
290     *
291     * @param string
292     *            the string representation of a float value.
293     * @return the primitive float value represented by {@code string}.
294     * @throws NumberFormatException
295     *             if {@code string} can not be parsed as a float value.
296     * @see #valueOf(String)
297     * @since 1.2
298     */
299    public static float parseFloat(String string) throws NumberFormatException {
300        return StringToReal.parseFloat(string);
301    }
302
303    @Override
304    public short shortValue() {
305        return (short) value;
306    }
307
308    @Override
309    public String toString() {
310        return Float.toString(value);
311    }
312
313    /**
314     * Returns a string containing a concise, human-readable description of the
315     * specified float value.
316     *
317     * @param f
318     *             the float to convert to a string.
319     * @return a printable representation of {@code f}.
320     */
321    public static String toString(float f) {
322        return RealToString.getInstance().floatToString(f);
323    }
324
325    /**
326     * Parses the specified string as a float value.
327     *
328     * @param string
329     *            the string representation of a float value.
330     * @return a {@code Float} instance containing the float value represented
331     *         by {@code string}.
332     * @throws NumberFormatException
333     *             if {@code string} can not be parsed as a float value.
334     * @see #parseFloat(String)
335     */
336    public static Float valueOf(String string) throws NumberFormatException {
337        return parseFloat(string);
338    }
339
340    /**
341     * Compares the two specified float values. There are two special cases:
342     * <ul>
343     * <li>{@code Float.NaN} is equal to {@code Float.NaN} and it is greater
344     * than any other float value, including {@code Float.POSITIVE_INFINITY};</li>
345     * <li>+0.0f is greater than -0.0f</li>
346     * </ul>
347     *
348     * @param float1
349     *            the first value to compare.
350     * @param float2
351     *            the second value to compare.
352     * @return a negative value if {@code float1} is less than {@code float2};
353     *         0 if {@code float1} and {@code float2} are equal; a positive
354     *         value if {@code float1} is greater than {@code float2}.
355     * @since 1.4
356     */
357    public static int compare(float float1, float float2) {
358        // Non-zero, non-NaN checking.
359        if (float1 > float2) {
360            return 1;
361        }
362        if (float2 > float1) {
363            return -1;
364        }
365        if (float1 == float2 && 0.0f != float1) {
366            return 0;
367        }
368
369        // NaNs are equal to other NaNs and larger than any other float
370        if (isNaN(float1)) {
371            if (isNaN(float2)) {
372                return 0;
373            }
374            return 1;
375        } else if (isNaN(float2)) {
376            return -1;
377        }
378
379        // Deal with +0.0 and -0.0
380        int f1 = floatToRawIntBits(float1);
381        int f2 = floatToRawIntBits(float2);
382        // The below expression is equivalent to:
383        // (f1 == f2) ? 0 : (f1 < f2) ? -1 : 1
384        // because f1 and f2 are either 0 or Integer.MIN_VALUE
385        return (f1 >> 31) - (f2 >> 31);
386    }
387
388    /**
389     * Returns a {@code Float} instance for the specified float value.
390     *
391     * @param f
392     *            the float value to store in the instance.
393     * @return a {@code Float} instance containing {@code f}.
394     * @since 1.5
395     */
396    public static Float valueOf(float f) {
397        return new Float(f);
398    }
399
400    /**
401     * Converts the specified float into its hexadecimal string representation.
402     *
403     * @param f
404     *            the float to convert.
405     * @return the hexadecimal string representation of {@code f}.
406     * @since 1.5
407     */
408    public static String toHexString(float f) {
409        /*
410         * Reference: http://en.wikipedia.org/wiki/IEEE_754-1985
411         */
412        if (f != f) {
413            return "NaN";
414        }
415        if (f == POSITIVE_INFINITY) {
416            return "Infinity";
417        }
418        if (f == NEGATIVE_INFINITY) {
419            return "-Infinity";
420        }
421
422        int bitValue = floatToIntBits(f);
423
424        boolean negative = (bitValue & 0x80000000) != 0;
425        // mask exponent bits and shift down
426        int exponent = (bitValue & 0x7f800000) >>> 23;
427        // mask significand bits and shift up
428        // significand is 23-bits, so we shift to treat it like 24-bits
429        int significand = (bitValue & 0x007FFFFF) << 1;
430
431        if (exponent == 0 && significand == 0) {
432            return (negative ? "-0x0.0p0" : "0x0.0p0");
433        }
434
435        StringBuilder hexString = new StringBuilder(10);
436        if (negative) {
437            hexString.append("-0x");
438        } else {
439            hexString.append("0x");
440        }
441
442        if (exponent == 0) { // denormal (subnormal) value
443            hexString.append("0.");
444            // significand is 23-bits, so there can be 6 hex digits
445            int fractionDigits = 6;
446            // remove trailing hex zeros, so Integer.toHexString() won't print
447            // them
448            while ((significand != 0) && ((significand & 0xF) == 0)) {
449                significand >>>= 4;
450                fractionDigits--;
451            }
452            // this assumes Integer.toHexString() returns lowercase characters
453            String hexSignificand = Integer.toHexString(significand);
454
455            // if there are digits left, then insert some '0' chars first
456            if (significand != 0 && fractionDigits > hexSignificand.length()) {
457                int digitDiff = fractionDigits - hexSignificand.length();
458                while (digitDiff-- != 0) {
459                    hexString.append('0');
460                }
461            }
462            hexString.append(hexSignificand);
463            hexString.append("p-126");
464        } else { // normal value
465            hexString.append("1.");
466            // significand is 23-bits, so there can be 6 hex digits
467            int fractionDigits = 6;
468            // remove trailing hex zeros, so Integer.toHexString() won't print
469            // them
470            while ((significand != 0) && ((significand & 0xF) == 0)) {
471                significand >>>= 4;
472                fractionDigits--;
473            }
474            // this assumes Integer.toHexString() returns lowercase characters
475            String hexSignificand = Integer.toHexString(significand);
476
477            // if there are digits left, then insert some '0' chars first
478            if (significand != 0 && fractionDigits > hexSignificand.length()) {
479                int digitDiff = fractionDigits - hexSignificand.length();
480                while (digitDiff-- != 0) {
481                    hexString.append('0');
482                }
483            }
484            hexString.append(hexSignificand);
485            hexString.append('p');
486            // remove exponent's 'bias' and convert to a string
487            hexString.append(exponent - 127);
488        }
489        return hexString.toString();
490    }
491}
492