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 
18 package java.lang;
19 
20 /**
21  * The wrapper for the primitive type {@code float}.
22  *
23  * @see java.lang.Number
24  * @since 1.0
25  */
26 public 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      */
Float(float value)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      */
Float(double value)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      */
Float(String string)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      */
compareTo(Float object)163     public int compareTo(Float object) {
164         return compare(value, object.value);
165     }
166 
167     @Override
byteValue()168     public byte byteValue() {
169         return (byte) value;
170     }
171 
172     @Override
doubleValue()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
equals(Object object)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      */
floatToIntBits(float value)202     public static int floatToIntBits(float value) {
203         if (value != value) {
204             return 0x7fc00000;  // NaN.
205         } else {
206             return floatToRawIntBits(value);
207         }
208     }
209 
210     /**
211      * Returns an integer corresponding to the bits of the given
212      * <a href="http://en.wikipedia.org/wiki/IEEE_754-1985">IEEE 754</a> single precision
213      * float {@code value}. <em>Not-a-Number (NaN)</em> values are preserved (compare
214      * to {@link #floatToIntBits}).
215      */
floatToRawIntBits(float value)216     public static native int floatToRawIntBits(float value);
217 
218     /**
219      * Gets the primitive value of this float.
220      *
221      * @return this object's primitive value.
222      */
223     @Override
floatValue()224     public float floatValue() {
225         return value;
226     }
227 
228     @Override
hashCode()229     public int hashCode() {
230         return floatToIntBits(value);
231     }
232 
233     /**
234      * Returns the <a href="http://en.wikipedia.org/wiki/IEEE_754-1985">IEEE 754</a>
235      * single precision float corresponding to the given {@code bits}.
236      */
intBitsToFloat(int bits)237     public static native float intBitsToFloat(int bits);
238 
239     @Override
intValue()240     public int intValue() {
241         return (int) value;
242     }
243 
244     /**
245      * Indicates whether this object represents an infinite value.
246      *
247      * @return {@code true} if the value of this float is positive or negative
248      *         infinity; {@code false} otherwise.
249      */
isInfinite()250     public boolean isInfinite() {
251         return isInfinite(value);
252     }
253 
254     /**
255      * Indicates whether the specified float represents an infinite value.
256      *
257      * @param f
258      *            the float to check.
259      * @return {@code true} if the value of {@code f} is positive or negative
260      *         infinity; {@code false} otherwise.
261      */
isInfinite(float f)262     public static boolean isInfinite(float f) {
263         return (f == POSITIVE_INFINITY) || (f == NEGATIVE_INFINITY);
264     }
265 
266     /**
267      * Indicates whether this object is a <em>Not-a-Number (NaN)</em> value.
268      *
269      * @return {@code true} if this float is <em>Not-a-Number</em>;
270      *         {@code false} if it is a (potentially infinite) float number.
271      */
isNaN()272     public boolean isNaN() {
273         return isNaN(value);
274     }
275 
276     /**
277      * Indicates whether the specified float is a <em>Not-a-Number (NaN)</em>
278      * value.
279      *
280      * @param f
281      *            the float value to check.
282      * @return {@code true} if {@code f} is <em>Not-a-Number</em>;
283      *         {@code false} if it is a (potentially infinite) float number.
284      */
isNaN(float f)285     public static boolean isNaN(float f) {
286         return f != f;
287     }
288 
289     @Override
longValue()290     public long longValue() {
291         return (long) value;
292     }
293 
294     /**
295      * Parses the specified string as a float value.
296      *
297      * @param string
298      *            the string representation of a float value.
299      * @return the primitive float value represented by {@code string}.
300      * @throws NumberFormatException
301      *             if {@code string} can not be parsed as a float value.
302      * @see #valueOf(String)
303      * @since 1.2
304      */
parseFloat(String string)305     public static float parseFloat(String string) throws NumberFormatException {
306         return StringToReal.parseFloat(string);
307     }
308 
309     @Override
shortValue()310     public short shortValue() {
311         return (short) value;
312     }
313 
314     @Override
toString()315     public String toString() {
316         return Float.toString(value);
317     }
318 
319     /**
320      * Returns a string containing a concise, human-readable description of the
321      * specified float value.
322      *
323      * @param f
324      *             the float to convert to a string.
325      * @return a printable representation of {@code f}.
326      */
toString(float f)327     public static String toString(float f) {
328         return RealToString.getInstance().floatToString(f);
329     }
330 
331     /**
332      * Parses the specified string as a float value.
333      *
334      * @param string
335      *            the string representation of a float value.
336      * @return a {@code Float} instance containing the float value represented
337      *         by {@code string}.
338      * @throws NumberFormatException
339      *             if {@code string} can not be parsed as a float value.
340      * @see #parseFloat(String)
341      */
valueOf(String string)342     public static Float valueOf(String string) throws NumberFormatException {
343         return parseFloat(string);
344     }
345 
346     /**
347      * Compares the two specified float values. There are two special cases:
348      * <ul>
349      * <li>{@code Float.NaN} is equal to {@code Float.NaN} and it is greater
350      * than any other float value, including {@code Float.POSITIVE_INFINITY};</li>
351      * <li>+0.0f is greater than -0.0f</li>
352      * </ul>
353      *
354      * @param float1
355      *            the first value to compare.
356      * @param float2
357      *            the second value to compare.
358      * @return a negative value if {@code float1} is less than {@code float2};
359      *         0 if {@code float1} and {@code float2} are equal; a positive
360      *         value if {@code float1} is greater than {@code float2}.
361      * @since 1.4
362      */
compare(float float1, float float2)363     public static int compare(float float1, float float2) {
364         // Non-zero, non-NaN checking.
365         if (float1 > float2) {
366             return 1;
367         }
368         if (float2 > float1) {
369             return -1;
370         }
371         if (float1 == float2 && 0.0f != float1) {
372             return 0;
373         }
374 
375         // NaNs are equal to other NaNs and larger than any other float
376         if (isNaN(float1)) {
377             if (isNaN(float2)) {
378                 return 0;
379             }
380             return 1;
381         } else if (isNaN(float2)) {
382             return -1;
383         }
384 
385         // Deal with +0.0 and -0.0
386         int f1 = floatToRawIntBits(float1);
387         int f2 = floatToRawIntBits(float2);
388         // The below expression is equivalent to:
389         // (f1 == f2) ? 0 : (f1 < f2) ? -1 : 1
390         // because f1 and f2 are either 0 or Integer.MIN_VALUE
391         return (f1 >> 31) - (f2 >> 31);
392     }
393 
394     /**
395      * Returns a {@code Float} instance for the specified float value.
396      *
397      * @param f
398      *            the float value to store in the instance.
399      * @return a {@code Float} instance containing {@code f}.
400      * @since 1.5
401      */
valueOf(float f)402     public static Float valueOf(float f) {
403         return new Float(f);
404     }
405 
406     /**
407      * Converts the specified float into its hexadecimal string representation.
408      *
409      * @param f
410      *            the float to convert.
411      * @return the hexadecimal string representation of {@code f}.
412      * @since 1.5
413      */
toHexString(float f)414     public static String toHexString(float f) {
415         /*
416          * Reference: http://en.wikipedia.org/wiki/IEEE_754-1985
417          */
418         if (f != f) {
419             return "NaN";
420         }
421         if (f == POSITIVE_INFINITY) {
422             return "Infinity";
423         }
424         if (f == NEGATIVE_INFINITY) {
425             return "-Infinity";
426         }
427 
428         int bitValue = floatToIntBits(f);
429 
430         boolean negative = (bitValue & 0x80000000) != 0;
431         // mask exponent bits and shift down
432         int exponent = (bitValue & 0x7f800000) >>> 23;
433         // mask significand bits and shift up
434         // significand is 23-bits, so we shift to treat it like 24-bits
435         int significand = (bitValue & 0x007FFFFF) << 1;
436 
437         if (exponent == 0 && significand == 0) {
438             return (negative ? "-0x0.0p0" : "0x0.0p0");
439         }
440 
441         StringBuilder hexString = new StringBuilder(10);
442         if (negative) {
443             hexString.append("-0x");
444         } else {
445             hexString.append("0x");
446         }
447 
448         if (exponent == 0) { // denormal (subnormal) value
449             hexString.append("0.");
450             // significand is 23-bits, so there can be 6 hex digits
451             int fractionDigits = 6;
452             // remove trailing hex zeros, so Integer.toHexString() won't print
453             // them
454             while ((significand != 0) && ((significand & 0xF) == 0)) {
455                 significand >>>= 4;
456                 fractionDigits--;
457             }
458             // this assumes Integer.toHexString() returns lowercase characters
459             String hexSignificand = Integer.toHexString(significand);
460 
461             // if there are digits left, then insert some '0' chars first
462             if (significand != 0 && fractionDigits > hexSignificand.length()) {
463                 int digitDiff = fractionDigits - hexSignificand.length();
464                 while (digitDiff-- != 0) {
465                     hexString.append('0');
466                 }
467             }
468             hexString.append(hexSignificand);
469             hexString.append("p-126");
470         } else { // normal value
471             hexString.append("1.");
472             // significand is 23-bits, so there can be 6 hex digits
473             int fractionDigits = 6;
474             // remove trailing hex zeros, so Integer.toHexString() won't print
475             // them
476             while ((significand != 0) && ((significand & 0xF) == 0)) {
477                 significand >>>= 4;
478                 fractionDigits--;
479             }
480             // this assumes Integer.toHexString() returns lowercase characters
481             String hexSignificand = Integer.toHexString(significand);
482 
483             // if there are digits left, then insert some '0' chars first
484             if (significand != 0 && fractionDigits > hexSignificand.length()) {
485                 int digitDiff = fractionDigits - hexSignificand.length();
486                 while (digitDiff-- != 0) {
487                     hexString.append('0');
488                 }
489             }
490             hexString.append(hexSignificand);
491             hexString.append('p');
492             // remove exponent's 'bias' and convert to a string
493             hexString.append(exponent - 127);
494         }
495         return hexString.toString();
496     }
497 }
498