Float源码阅读(1.8)

445 阅读4分钟

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) 的表示其实可以这样表示:

image.png

以单精度浮点数为例:

image.png

  • 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]。
TypeSignExponentSignificand fieldTotalExponent BiasBits PrecisionNumber of decimal digits
Half1510161511~3.3
Single18233212724~7.2
Double1115264102353~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);
    }