# 走进 JDK 之 Float

Float.java

Float.c

``````0.3f - 0.2f = ?

``````0.10000001

``````12.34 = 1 * 10^1 + 2 * 10^0 + 3 * 10^-1 + 4 * 10^-2

``````10.11 b = 1 * 2^1 + 0 * 2^0 + 1 * 2^-1 + 1 * 2^-2
= 2 + 1/2 + 1/4
= 2.75

``````1.75 = 1 + 3/4
= 7/4
= 7 * 2^-2

`7` 的二进制表示为 `111``* 2^-2` 表示将小数点左移两位，得到 `1.11`。所以，`1.75 = 1.11b`

0.1 2 ^ -1 0.5
0.01 2 ^ -2 0.25
0.001 2 ^ -3 0.125
0.0001 2 ^ -4 0.0625
0.00001 2 ^ -5 0.03125

• sign : 符号位，`1` 位 。`0` 表示正数， `1` 表示负数。用 `s` 表示
• exponent ： 阶码域，`8` 位。用 `E` 表示，通常 `E = exponent - 127`,`exponent` 为无符号数
• fraction : 尾数域，`23` 位。用 `M` 表示，通常 `M = 1.fraction`

``````V = (-1)^s * M * 2^E

``````V = (-1)^0 * 1.01 * 2^-3 = 0.00101 b = 0.15625

## 类声明

``````public final class Float extends Number implements Comparable<Float>{}

## 字段

``````private final float value;
private static final long serialVersionUID = -2671257302660747028L;
public static final Class<Float> TYPE = (Class<Float>) Class.getPrimitiveClass("float");

`final` 修饰的 `value` 字段保证其不可变性，`value` 也是 `Float` 类所包装的浮点数。

``````// 0 11111111 00000000000000000000000
public static final float POSITIVE_INFINITY = 1.0f / 0.0f;
// 1 11111111 00000000000000000000000
public static final float NEGATIVE_INFINITY = -1.0f / 0.0f;

``````// 0 11111111 10000000000000000000000
public static final float NaN = 0.0f / 0.0f;

`Not a number`，非数字。阶码域都为 `1`，尾数域不全为 `0`

``````// 0 11111110 11111111111111111111111
public static final float MAX_VALUE = 0x1.fffffeP+127f;

``````/*
* 0 00000001 00000000000000000000000
* 最小的规格化数（正数）
*/
public static final float MIN_NORMAL = 0x1.0p-126f; // 1.17549435E-38f

/*
* 0 00000000 00000000000000000000001
* 最小的非规格化数（正数）
*/
public static final float MIN_VALUE = 0x0.000002P-126f;

``````E = exponent - 127
M = 1.fraction
V = (-1)^s * M * 2^E

``````E = 1 - 127 = -126
M = 0.fraction
V = (-1)^s * M * 2^E

``````public static final int MAX_EXPONENT = 127; // 指数域（阶码）最大值
public static final int MIN_EXPONENT = -126; // 指数域（阶码）最小值
public static final int SIZE = 32; // float 占 32 bits
public static final int BYTES = SIZE / Byte.SIZE; // float 占 4 bytes

## 构造函数

``````public Float(float value) {
this.value = value;
}

public Float(double value) {
this.value = (float)value;
}

public Float(String s) throws NumberFormatException {
value = parseFloat(s);
}

`Float` 有三个构造函数。第一个直接传入 `float` 值。第二个传入 `double` 值，再强转 `float`。第三个传入 `String`，调用 `parseFloat()` 函数转换成 `float`。下面就来看看这个 `parseFloat` 函数。

## 方法

### parseFloat(String)

``````public static float parseFloat(String s) throws NumberFormatException {
return FloatingDecimal.parseFloat(s);
}

• 首先取出符号位，判断正数还是负数
• 判断是否为 `NaN`
• 判断是否为 `Infinity`
• 判断是否是以 `0x``0X` 开头的十六进制浮点数。若是，调用 `parseHexString()` 方法处理
• 跳过开头的无效的 `0`
• 循环取出各位数字。注意若包含 `e` 或者 `E`,需要注意科学计数法的处理
• 根据取得的字符数组等信息构建 `ASCIIToBinaryBuffer` 对象，调用其 `floatValue()` 方法，获取最终结果

### valueOf(String)

``````    public static Float valueOf(String s) throws NumberFormatException {
return new Float(parseFloat(s));
}

### toString()

``````public String toString() {
return Float.toString(value);
}

public static String toString(float f) {
return FloatingDecimal.toJavaFormatString(f);
}

### isNaN()

``````public static boolean isNaN(float v) {
return (v != v);
}

### isInfinite()

``````public boolean isInfinite() {
return isInfinite(value);
}

public static boolean isInfinite(float v) {
return (v == POSITIVE_INFINITY) || (v == NEGATIVE_INFINITY);
}

### isFinite()

``````public static boolean isFinite(float f) {
return Math.abs(f) <= FloatConsts.MAX_VALUE;
}

### 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;   }

### floatToRawIntBits(float)

``````public static native int floatToRawIntBits(float value);

``````JNIEXPORT jint JNICALL
Java_java_lang_Float_floatToRawIntBits(JNIEnv *env, jclass unused, jfloat v)
{
union {
int i;
float f;
} u;
u.f = (float)v;
return (jint)u.i;
}

`union` 是一种数据结构，它能在同一个内存空间中储存不同的数据类型，也就是说同一块内存，它可以表示 `float` , 也可以表示 `int`。通过 `union``float` 转换为其二进制对应的 `int` 值。

### floatToIntBits(float)

``````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) ==
result = 0x7fc00000;
return result;
}

``````((result & FloatConsts.EXP_BIT_MASK) == FloatConsts.EXP_BIT_MASK) &&

### intBitsToFloat(int)

``````public static native float intBitsToFloat(int bits);

Java_java_lang_Float_intBitsToFloat(JNIEnv *env, jclass unused, jint v)
{
union {
int i;
float f;
} u;
u.i = (long)v;
return (jfloat)u.f;
}

`native` 方法，也是通过联合体 `union` 来实现的。只要参数中的 `int` 值满足 `IEEE 754` 对于 `NaN` 的标准，就可以产生值不为 `Float.NaN``NaN` 值了。

### hashCode()

``````@Override
public int hashCode() {
return Float.hashCode(value);
}

public static int hashCode(float value) {
return floatToIntBits(value);
}

`hashCode()` 函数直接调用 `floatToIntBits()` 方法，返回其二进制对应的 `int` 值。

### equals()

``````public boolean equals(Object obj) {
return (obj instanceof Float)
&& (floatToIntBits(((Float)obj).value) == floatToIntBits(value));
}

`equals` 的条件是其 `IEEE 754` 标准的二进制形式相等。

## 总结

`Float` 就说到这里了。这篇源码解释不是很多，主要说明了 `Float` 在内存中的二进制形式，也就是 `IEEE 754` 标准。了解了 `IEEE 754`，对于浮点数也就了然于心了。最后再推荐一下 《深入理解计算机系统》`2.4` 节关于浮点数的介绍。

Android