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 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 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 102 // Note: This can't be set to "float.class", since *that* is 103 // defined to be "java.lang.Float.TYPE"; 104 105 /** 106 * Constant for the number of bits needed to represent a {@code float} in 107 * two's complement form. 108 * 109 * @since 1.5 110 */ 111 public static final int SIZE = 32; 112 113 /** 114 * Constructs a new {@code Float} with the specified primitive float value. 115 * 116 * @param value 117 * the primitive float value to store in the new instance. 118 */ Float(float value)119 public Float(float value) { 120 this.value = value; 121 } 122 123 /** 124 * Constructs a new {@code Float} with the specified primitive double value. 125 * 126 * @param value 127 * the primitive double value to store in the new instance. 128 */ Float(double value)129 public Float(double value) { 130 this.value = (float) value; 131 } 132 133 /** 134 * Constructs a new {@code Float} from the specified string. 135 * 136 * @param string 137 * the string representation of a float value. 138 * @throws NumberFormatException 139 * if {@code string} can not be decoded into a float value. 140 * @see #parseFloat(String) 141 */ Float(String string)142 public Float(String string) throws NumberFormatException { 143 this(parseFloat(string)); 144 } 145 146 /** 147 * Compares this object to the specified float object to determine their 148 * relative order. There are two special cases: 149 * <ul> 150 * <li>{@code Float.NaN} is equal to {@code Float.NaN} and it is greater 151 * than any other float value, including {@code Float.POSITIVE_INFINITY};</li> 152 * <li>+0.0f is greater than -0.0f</li> 153 * </ul> 154 * 155 * @param object 156 * the float object to compare this object to. 157 * @return a negative value if the value of this float is less than the 158 * value of {@code object}; 0 if the value of this float and the 159 * value of {@code object} are equal; a positive value if the value 160 * of this float is greater than the value of {@code object}. 161 * @see java.lang.Comparable 162 * @since 1.2 163 */ compareTo(Float object)164 public int compareTo(Float object) { 165 return compare(value, object.value); 166 } 167 168 @Override byteValue()169 public byte byteValue() { 170 return (byte) value; 171 } 172 173 @Override doubleValue()174 public double doubleValue() { 175 return value; 176 } 177 178 /** 179 * Tests this double for equality with {@code object}. 180 * To be equal, {@code object} must be an instance of {@code Float} and 181 * {@code floatToIntBits} must give the same value for both objects. 182 * 183 * <p>Note that, unlike {@code ==}, {@code -0.0} and {@code +0.0} compare 184 * unequal, and {@code NaN}s compare equal by this method. 185 * 186 * @param object 187 * the object to compare this float with. 188 * @return {@code true} if the specified object is equal to this 189 * {@code Float}; {@code false} otherwise. 190 */ 191 @Override equals(Object object)192 public boolean equals(Object object) { 193 return (object == this) 194 || (object instanceof Float) 195 && (floatToIntBits(this.value) == floatToIntBits(((Float) object).value)); 196 } 197 198 /** 199 * Converts the specified float value to a binary representation conforming 200 * to the IEEE 754 floating-point single precision bit layout. All 201 * <em>Not-a-Number (NaN)</em> values are converted to a single NaN 202 * representation ({@code 0x7fc00000}). 203 * 204 * @param value 205 * the float value to convert. 206 * @return the IEEE 754 floating-point single precision representation of 207 * {@code value}. 208 * @see #floatToRawIntBits(float) 209 * @see #intBitsToFloat(int) 210 */ floatToIntBits(float value)211 public static native int floatToIntBits(float value); 212 213 /** 214 * Converts the specified float value to a binary representation conforming 215 * to the IEEE 754 floating-point single precision bit layout. 216 * <em>Not-a-Number (NaN)</em> values are preserved. 217 * 218 * @param value 219 * the float value to convert. 220 * @return the IEEE 754 floating-point single precision representation of 221 * {@code value}. 222 * @see #floatToIntBits(float) 223 * @see #intBitsToFloat(int) 224 */ floatToRawIntBits(float value)225 public static native int floatToRawIntBits(float value); 226 227 /** 228 * Gets the primitive value of this float. 229 * 230 * @return this object's primitive value. 231 */ 232 @Override floatValue()233 public float floatValue() { 234 return value; 235 } 236 237 @Override hashCode()238 public int hashCode() { 239 return floatToIntBits(value); 240 } 241 242 /** 243 * Converts the specified IEEE 754 floating-point single precision bit 244 * pattern to a Java float value. 245 * 246 * @param bits 247 * the IEEE 754 floating-point single precision representation of 248 * a float value. 249 * @return the float value converted from {@code bits}. 250 * @see #floatToIntBits(float) 251 * @see #floatToRawIntBits(float) 252 */ intBitsToFloat(int bits)253 public static native float intBitsToFloat(int bits); 254 255 @Override intValue()256 public int intValue() { 257 return (int) value; 258 } 259 260 /** 261 * Indicates whether this object represents an infinite value. 262 * 263 * @return {@code true} if the value of this float is positive or negative 264 * infinity; {@code false} otherwise. 265 */ isInfinite()266 public boolean isInfinite() { 267 return isInfinite(value); 268 } 269 270 /** 271 * Indicates whether the specified float represents an infinite value. 272 * 273 * @param f 274 * the float to check. 275 * @return {@code true} if the value of {@code f} is positive or negative 276 * infinity; {@code false} otherwise. 277 */ isInfinite(float f)278 public static boolean isInfinite(float f) { 279 return (f == POSITIVE_INFINITY) || (f == NEGATIVE_INFINITY); 280 } 281 282 /** 283 * Indicates whether this object is a <em>Not-a-Number (NaN)</em> value. 284 * 285 * @return {@code true} if this float is <em>Not-a-Number</em>; 286 * {@code false} if it is a (potentially infinite) float number. 287 */ isNaN()288 public boolean isNaN() { 289 return isNaN(value); 290 } 291 292 /** 293 * Indicates whether the specified float is a <em>Not-a-Number (NaN)</em> 294 * value. 295 * 296 * @param f 297 * the float value to check. 298 * @return {@code true} if {@code f} is <em>Not-a-Number</em>; 299 * {@code false} if it is a (potentially infinite) float number. 300 */ isNaN(float f)301 public static boolean isNaN(float f) { 302 return f != f; 303 } 304 305 @Override longValue()306 public long longValue() { 307 return (long) value; 308 } 309 310 /** 311 * Parses the specified string as a float value. 312 * 313 * @param string 314 * the string representation of a float value. 315 * @return the primitive float value represented by {@code string}. 316 * @throws NumberFormatException 317 * if {@code string} is {@code null}, has a length of zero or 318 * can not be parsed as a float value. 319 * @see #valueOf(String) 320 * @since 1.2 321 */ parseFloat(String string)322 public static float parseFloat(String string) throws NumberFormatException { 323 return org.apache.harmony.luni.util.FloatingPointParser 324 .parseFloat(string); 325 } 326 327 @Override shortValue()328 public short shortValue() { 329 return (short) value; 330 } 331 332 @Override toString()333 public String toString() { 334 return Float.toString(value); 335 } 336 337 /** 338 * Returns a string containing a concise, human-readable description of the 339 * specified float value. 340 * 341 * @param f 342 * the float to convert to a string. 343 * @return a printable representation of {@code f}. 344 */ toString(float f)345 public static String toString(float f) { 346 return RealToString.getInstance().floatToString(f); 347 } 348 349 /** 350 * Parses the specified string as a float value. 351 * 352 * @param string 353 * the string representation of a float value. 354 * @return a {@code Float} instance containing the float value represented 355 * by {@code string}. 356 * @throws NumberFormatException 357 * if {@code string} is {@code null}, has a length of zero or 358 * can not be parsed as a float value. 359 * @see #parseFloat(String) 360 */ valueOf(String string)361 public static Float valueOf(String string) throws NumberFormatException { 362 return parseFloat(string); 363 } 364 365 /** 366 * Compares the two specified float values. There are two special cases: 367 * <ul> 368 * <li>{@code Float.NaN} is equal to {@code Float.NaN} and it is greater 369 * than any other float value, including {@code Float.POSITIVE_INFINITY};</li> 370 * <li>+0.0f is greater than -0.0f</li> 371 * </ul> 372 * 373 * @param float1 374 * the first value to compare. 375 * @param float2 376 * the second value to compare. 377 * @return a negative value if {@code float1} is less than {@code float2}; 378 * 0 if {@code float1} and {@code float2} are equal; a positive 379 * value if {@code float1} is greater than {@code float2}. 380 * @since 1.4 381 */ compare(float float1, float float2)382 public static int compare(float float1, float float2) { 383 // Non-zero, non-NaN checking. 384 if (float1 > float2) { 385 return 1; 386 } 387 if (float2 > float1) { 388 return -1; 389 } 390 if (float1 == float2 && 0.0f != float1) { 391 return 0; 392 } 393 394 // NaNs are equal to other NaNs and larger than any other float 395 if (isNaN(float1)) { 396 if (isNaN(float2)) { 397 return 0; 398 } 399 return 1; 400 } else if (isNaN(float2)) { 401 return -1; 402 } 403 404 // Deal with +0.0 and -0.0 405 int f1 = floatToRawIntBits(float1); 406 int f2 = floatToRawIntBits(float2); 407 // The below expression is equivalent to: 408 // (f1 == f2) ? 0 : (f1 < f2) ? -1 : 1 409 // because f1 and f2 are either 0 or Integer.MIN_VALUE 410 return (f1 >> 31) - (f2 >> 31); 411 } 412 413 /** 414 * Returns a {@code Float} instance for the specified float value. 415 * 416 * @param f 417 * the float value to store in the instance. 418 * @return a {@code Float} instance containing {@code f}. 419 * @since 1.5 420 */ valueOf(float f)421 public static Float valueOf(float f) { 422 return new Float(f); 423 } 424 425 /** 426 * Converts the specified float into its hexadecimal string representation. 427 * 428 * @param f 429 * the float to convert. 430 * @return the hexadecimal string representation of {@code f}. 431 * @since 1.5 432 */ toHexString(float f)433 public static String toHexString(float f) { 434 /* 435 * Reference: http://en.wikipedia.org/wiki/IEEE_754 436 */ 437 if (f != f) { 438 return "NaN"; 439 } 440 if (f == POSITIVE_INFINITY) { 441 return "Infinity"; 442 } 443 if (f == NEGATIVE_INFINITY) { 444 return "-Infinity"; 445 } 446 447 int bitValue = floatToIntBits(f); 448 449 boolean negative = (bitValue & 0x80000000) != 0; 450 // mask exponent bits and shift down 451 int exponent = (bitValue & 0x7f800000) >>> 23; 452 // mask significand bits and shift up 453 // significand is 23-bits, so we shift to treat it like 24-bits 454 int significand = (bitValue & 0x007FFFFF) << 1; 455 456 if (exponent == 0 && significand == 0) { 457 return (negative ? "-0x0.0p0" : "0x0.0p0"); 458 } 459 460 StringBuilder hexString = new StringBuilder(10); 461 if (negative) { 462 hexString.append("-0x"); 463 } else { 464 hexString.append("0x"); 465 } 466 467 if (exponent == 0) { // denormal (subnormal) value 468 hexString.append("0."); 469 // significand is 23-bits, so there can be 6 hex digits 470 int fractionDigits = 6; 471 // remove trailing hex zeros, so Integer.toHexString() won't print 472 // them 473 while ((significand != 0) && ((significand & 0xF) == 0)) { 474 significand >>>= 4; 475 fractionDigits--; 476 } 477 // this assumes Integer.toHexString() returns lowercase characters 478 String hexSignificand = Integer.toHexString(significand); 479 480 // if there are digits left, then insert some '0' chars first 481 if (significand != 0 && fractionDigits > hexSignificand.length()) { 482 int digitDiff = fractionDigits - hexSignificand.length(); 483 while (digitDiff-- != 0) { 484 hexString.append('0'); 485 } 486 } 487 hexString.append(hexSignificand); 488 hexString.append("p-126"); 489 } else { // normal value 490 hexString.append("1."); 491 // significand is 23-bits, so there can be 6 hex digits 492 int fractionDigits = 6; 493 // remove trailing hex zeros, so Integer.toHexString() won't print 494 // them 495 while ((significand != 0) && ((significand & 0xF) == 0)) { 496 significand >>>= 4; 497 fractionDigits--; 498 } 499 // this assumes Integer.toHexString() returns lowercase characters 500 String hexSignificand = Integer.toHexString(significand); 501 502 // if there are digits left, then insert some '0' chars first 503 if (significand != 0 && fractionDigits > hexSignificand.length()) { 504 int digitDiff = fractionDigits - hexSignificand.length(); 505 while (digitDiff-- != 0) { 506 hexString.append('0'); 507 } 508 } 509 hexString.append(hexSignificand); 510 hexString.append('p'); 511 // remove exponent's 'bias' and convert to a string 512 hexString.append(exponent - 127); 513 } 514 return hexString.toString(); 515 } 516 } 517