Float是基本数据类型float的包装类,提供了一些处理float类型的方法,一起来看看吧^_^
类定义
public final class Float extends Number implements Comparable<Float>
public abstract class Number implements java.io.Serializable
- 可以看到Float类继承了Number类、实现了Comparable接口,且是final不可继承的。
- 在深入源码之前先来了解一些基础知识。
IEEE 754
- IEEE二进制浮点数算术标准(IEEE 754)是20世纪80年代以来最广泛使用的浮点数运算标准,为许多CPU与浮点运算器所采用。这个标准定义了表示浮点数的格式(包括负零-0)与反常值(denormal number)),一些特殊数值(无穷(Inf)与非数值(NaN)),以及这些数值的“浮点数运算符”;它也指明了四种数值舍入规则和五种例外状况(包括例外发生的时机与处理方式)。
- IEEE 754规定了四种表示浮点数值的方式:单精确度(32位)、双精确度(64位)、延伸单精确度(43比特以上,很少使用)与延伸双精确度(79比特以上,通常以80位实现)。Java的Float就是单精确度的实现。
浮点数表示
一个浮点数 (Value) 的表示其实可以这样表示:
以单精度浮点数为例:
- sign:正数
- exponent:2^-3
- fraction:1.01(2进制)
- value=0.00101(2^-3相当于右移3位)=5/32=0.15625 float的指数位是无符号的,它的正负区分通过采用一个偏移值来确定,下表可以查到float单精度的偏移值是127。偏移前表达范围[0,255],经过偏移后,8位指数位所能表达的范围是:[-127,128]。
Type | Sign | Exponent | Significand field | Total | Exponent Bias | Bits Precision | Number of decimal digits | |
---|---|---|---|---|---|---|---|---|
Half | 1 | 5 | 10 | 16 | 15 | 11 | ~3.3 | |
Single | 1 | 8 | 23 | 32 | 127 | 24 | ~7.2 | |
Double | 1 | 11 | 52 | 64 | 1023 | 53 | ~15.9 |
但是float是需要表达NaN-not a number与Inf-Infinite的,此时指数位需要来标示,所以全1情况被用掉,另外0特殊表达,指数全0情况也被用掉。 所以去掉一个最大值,一个最小值,指数表达的范围是:[-126,127] // 指数位全1时表达的Infinite
- 0 11111111 00000000000000000000000 = 7f80 000016 = infinity
- 1 11111111 00000000000000000000000 = ff80 000016 = −infinity // 指数位全1时表达的NaN
- x 11111111 10000000000000000000001 = ffc0 000116 = qNaN (on x86 and ARM processors)
- x 11111111 00000000000000000000001 = ff80 000116 = sNaN (on x86 and ARM processors) // 指数与精度位全0时表达的+0, -0
- 0 00000000 00000000000000000000000 = 0000 000016 = 0
- 1 00000000 00000000000000000000000 = 8000 000016 = −0
成员变量
public static final float POSITIVE_INFINITY = 1.0f / 0.0f; //正无穷
public static final float NEGATIVE_INFINITY = -1.0f / 0.0f; //负无穷
public static final float NaN = 0.0f / 0.0f; //表示不是一个数字
public static final float MAX_VALUE = 0x1.fffffeP+127f; // 3.4028235e+38f 能表示的最大浮点数
public static final float MIN_NORMAL = 0x1.0p-126f; // 1.17549435E-38f 能表示的正最小浮点数
public static final float MIN_VALUE = 0x0.000002P-126f; // 1.4e-45f 能表示的最小浮点数
public static final int MAX_EXPONENT = 127;//一个有限float数值的最大指数值
public static final int MIN_EXPONENT = -126;//一个有限float数值的最小指数值
public static final int SIZE = 32;
public static final int BYTES = SIZE / Byte.SIZE;//4字节
public static final Class<Float> TYPE = (Class<Float>) Class.getPrimitiveClass("float");
private final float value;
private static final long serialVersionUID = -2671257302660747028L;
构造方法
public Float(float value) {
this.value = value;
}
public Float(double value) {
this.value = (float)value;
}
public Float(String s) throws NumberFormatException {
value = parseFloat(s);
}
//通过FloatingDecimal类来完成string->float
public static float parseFloat(String s) throws NumberFormatException {
return FloatingDecimal.parseFloat(s);
}
valueOf系列方法
public static Float valueOf(String s) throws NumberFormatException {
return new Float(parseFloat(s));
}
public static Float valueOf(float f) {
return new Float(f);
}
Number 父类方法实现
public byte byteValue() {
return (byte)value;
}
public short shortValue() {
return (short)value;
}
public int intValue() {
return (int)value;
}
public long longValue() {
return (long)value;
}
public float floatValue() {
return value;
}
public double doubleValue() {
return (double)value;
}
都是强转......
isXXX
public boolean isNaN() {
return isNaN(value);
}
//NaN和任何值都不等包括它自生
public static boolean isNaN(float v) {
return (v != v);
}
public boolean isInfinite() {
return isInfinite(value);
}
public static boolean isInfinite(float v) {
return (v == POSITIVE_INFINITY) || (v == NEGATIVE_INFINITY);
}
public static boolean isFinite(float f) {
return Math.abs(f) <= FloatConsts.MAX_VALUE;
}
toString
public String toString() {
return Float.toString(value);
}
public static String toString(float f) {
return FloatingDecimal.toJavaFormatString(f);
}
//0x0.0p0 0.0f
//0x1.0p-1 0.5f
//0x1.99999ap-5 0.05f
//0x1.47ae14p-8 0.005f
public static String toHexString(float f) {
if (Math.abs(f) < FloatConsts.MIN_NORMAL
&& f != 0.0f ) {// float subnormal
// Adjust exponent to create subnormal double, then
// replace subnormal double exponent with subnormal float
// exponent
String s = Double.toHexString(Math.scalb((double)f,
/* -1022+126 */
DoubleConsts.MIN_EXPONENT-
FloatConsts.MIN_EXPONENT));
return s.replaceFirst("p-1022$", "p-126");
}
else // double string will be the same as float string
return Double.toHexString(f);
}
hashcode
@Override
public int hashCode() {
return Float.hashCode(value);
}
public static int hashCode(float value) {
return floatToIntBits(value);
}
public static int floatToIntBits(float value) {
int result = floatToRawIntBits(value);
// Check for NaN based on values of bit fields, maximum
// exponent and nonzero significand.
if ( ((result & FloatConsts.EXP_BIT_MASK) ==
FloatConsts.EXP_BIT_MASK) &&
(result & FloatConsts.SIGNIF_BIT_MASK) != 0)
result = 0x7fc00000;
return result;
}
比较
public boolean equals(Object obj) {
return (obj instanceof Float)
&& (floatToIntBits(((Float)obj).value) == floatToIntBits(value));
}
public int compareTo(Float anotherFloat) {
return Float.compare(value, anotherFloat.value);
}
public static int compare(float f1, float f2) {
if (f1 < f2)
return -1; // Neither val is NaN, thisVal is smaller
if (f1 > f2)
return 1; // Neither val is NaN, thisVal is larger
// Cannot use floatToRawIntBits because of possibility of NaNs.
int thisBits = Float.floatToIntBits(f1);
int anotherBits = Float.floatToIntBits(f2);
return (thisBits == anotherBits ? 0 : // Values are equal
(thisBits < anotherBits ? -1 : // (-0.0, 0.0) or (!NaN, NaN)
1)); // (0.0, -0.0) or (NaN, !NaN)
}
运算
public static float sum(float a, float b) {
return a + b;
}
public static float max(float a, float b) {
return Math.max(a, b);
}
public static float min(float a, float b) {
return Math.min(a, b);
}