Float

      终于见到小数了!Float是float的包装类,提供了一些处理float类型的方法,一起来看看吧^_^

IEEE 754

      IEEE二进制浮点数算术标准(IEEE 754)是20世纪80年代以来最广泛使用的浮点数运算标准,为许多CPU与浮点运算器所采用。这个标准定义了表示浮点数的格式(包括负零-0)与反常值(denormal number)),一些特殊数值(无穷(Inf)与非数值(NaN)),以及这些数值的“浮点数运算符”;它也指明了四种数值舍入规则和五种例外状况(包括例外发生的时机与处理方式)。

      IEEE 754规定了四种表示浮点数值的方式:单精确度(32位)、双精确度(64位)、延伸单精确度(43比特以上,很少使用)与延伸双精确度(79比特以上,通常以80位实现)。Java的Float就是单精确度的实现。

浮点数的剖析

浮点数的二进制如下图表示:
浮点数二进制表示

其中,sign:符号位(1为负数,0为正数);exponent:指数偏移值,fraction:分数值。

一个浮点数 (Value) 的值为:
计算公式

小试牛刀:
二进制01000001001101100000000000000000表示的浮点数是什么?
符号位为0,正数;
指数偏移值为10000010,减去127为3;
分数值为1.011011,
浮点数为1011.011(*2^3,小数时相当于右移3),转为十进制为11.375

Float类图

Float类图

public final class Float extends Number implements Comparable<Float>

      通过类图和源码我们可以知道Float是不可被继承的,并且Float类型的实例对象是可以比较的。由于Float继承了Number(这是一个抽象类),所以Float重写了其所有形如xxxValue的方法。
Number

成员变量

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;//NaN
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;//exponent最大值。
public static final int MIN_EXPONENT = -126;//exponent最小值
public static final int SIZE = 32;//32位
public static final int BYTES = SIZE / Byte.SIZE;//4字节
private final float value;
public static final Class<Float> TYPE = (Class<Float>) Class.getPrimitiveClass("float");

      Float对象的值保持在value中,并且value是不可变的。

构造方法

public Float(float value) {
    this.value = value;
}
public Float(double value) {
    this.value = (float)value;
}
public Float(String s) throws NumberFormatException {
    value = parseFloat(s);
}
public static float parseFloat(String s) throws NumberFormatException {
    return FloatingDecimal.parseFloat(s);
}

      Float有三个构造方法,可传入float,double,String类型的值,其中String会借助FloatingDecimal的parseFloat方法进行转换。

valueOf

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

      与Byte,Integer等包装类的valueOf可从缓存中获取-128~127范围内的对象不同,Float调用valueOf都是new实例。

xxxValue

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

      这六个方法都是继承自Number类,将value值强转为对应的类型。

toString

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

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

      返回f的字符串表示。如果f是NaN,返回"NaN";如果f是负数则以'-'为起始标识,正数无标识;如果f是infinity,正数返回Infinity,负数返回-Infinity;如果f是0.0,-0.0返回"-0.0",0.0返回"0.0";如果f<10^-3或f>=10^7则使用科学计数法表示。

isXXX

public boolean isNaN() {
    return isNaN(value);
}
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;
}

      通过isNaN方法我们可以了解到Float.NaN != Float.NaN。Java 提供的任何 IEEE 754 浮点操作都不能区分具有不同位模式的两个同类型 NaN 值。不同的 NaN 值只能使用 Float.floatToRawLongBits 方法区分。

max/min

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

hashCode

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

/**
 * 先通过调用floatToRawIntBits获取到IEEE 754标准对应的整型数,然后再分别用 
 * FloatConsts.EXP_BIT_MASK和FloatConsts.SIGNIF_BIT_MASK两个掩码去判断是否为NaN,0x7fc00000对 
 * 应的即为NaN。
 */
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;
}

      返回IEEE 754标准对应的整型数。与floatToIntBits先对的方法是intBitsToFloat,它返回对应于给定位表示形式的 float值。如如果参数为 0x7f800000,则结果为正无穷大。如果参数为 0xff800000,则结果为负无穷大。如果参数值在 0x7f800001 到 0x7fffffff 或在 0xff800001 到 0xffffffff 之间,则结果为 NaN。Java 提供的任何 IEEE 754 浮点操作都不能区分具有不同位模式的两个同类型 NaN 值。不同的 NaN 值只能使用 Float.floatToRawIntBits 方法区分。

equals

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

      首先判断是否为Float对象,如果是则比较floatToLongBits方法的返回值是否相等。

compareTo

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

    // 不能使用floatToRawIntBits方法,因为可能为NaN.
    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)
}

      f1小于f2则返回-1,反之则返回1。无法通过上述直接比较时则使用floatToIntBits方法分别将f1和f2转成IEEE 754标准对应的整型数,然后再比较。相等则返回0,否则返回-1或1。注意:正0比负0大;NaN比任何非NaN的数都大。

Last modification:September 8th, 2019 at 10:30 pm
如果觉得我的文章对你有用,请随意赞赏