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