美文网首页
9 java.lang.Float

9 java.lang.Float

作者: 十丈_红尘 | 来源:发表于2018-09-24 21:02 被阅读0次

1️⃣类定义

public final class Float extends Number implements Comparable<Float>
  1. 声明为final,不能被继承;
  2. 继承Number,可以进行Number类型之间的转换;
  3. 实现了Comparable,可以进行比较;

2️⃣属性

    /**
     * 正无穷 : 程序运行值为 Infinity(无穷)
     */
    public static final float POSITIVE_INFINITY = 1.0f / 0.0f;

    /**
     * 负无穷 : 程序运行值为 -Infinity(负无穷)
     */
    public static final float NEGATIVE_INFINITY = -1.0f / 0.0f;

    /**
     * 非数字的float变量运行值为 NaN
     */
    public static final float NaN = 0.0f / 0.0f;

    /**
     * 最大值 : 3.4028235e+38f
     */
    public static final float MAX_VALUE = 0x1.fffffeP+127f;

    /**
     * 最小值 : 1.17549435E-38f
     */
    public static final float MIN_NORMAL = 0x1.0p-126f;

    /**
     * 最小正数值
     */
    public static final float MIN_VALUE = 0x0.000002P-126f; // 1.4e-45f

    /**
     * 指数的最大值
     */
    public static final int MAX_EXPONENT = 127;

    /**
     * 指数的最小值
     */
    public static final int MIN_EXPONENT = -126;

    /**
     * 所占的位数(32位)
     */
    public static final int SIZE = 32;

    /**
     * 字节数4个字节 ,这里除的是Byte的静态变量Byte.SIZE大小是8
     */
    public static final int BYTES = SIZE / Byte.SIZE;

    /**
     * @SuppressWarnings("unchecked")表示对警告保持静默 
     * 获取Float的原始class对象
     */
    @SuppressWarnings("unchecked")
    public static final Class<Float> TYPE = (Class<Float>) Class.getPrimitiveClass("float");

    /**
     * float对象中具体的float值,定义为final
     */
    private final float value;
    
    /**
     * 序列化
     */
    private static final long serialVersionUID = -2671257302660747028L;

3️⃣构造器

    /**
     * 直接把float赋值给value属性
     */
    public Float(float value) {
        this.value = value;
    }

    /**
     * 将double赋值给value属性并进行类型强转
     */
    public Float(double value) {
        this.value = (float)value;
    }

    /**
     * 将string转化为float,底层调用FloatingDecimal类的parseFloat()方法
     * 来解析单精度浮点小数,在parseFloat()方法内进行一通解析操作(与double
     * 的底层解析一样,调用的都是readJavaFormatString()方法;
     */
    public Float(String s) throws NumberFormatException {
        value = parseFloat(s);
    }

4️⃣方法

① toString()

    /**
     * 底层调用FloatingDecimal.toJavaFormatString(d)方法进行解析
     */
    public static String toString(float f) {
        return FloatingDecimal.toJavaFormatString(f);
    }
    
    /**
     * 底层调用的是该类静态的toString()方法
     */
    public String toString() {
        return Float.toString(value);
    }

② toHexString()

    /**
     * 将float转为16进制的字符串
     */
    public static String toHexString(float f) {
        /**
         * 如果float的绝对值小于最小的正常值(public static final float MIN_NORMAL = 1.17549435E-38F;)
         * 且float不等于0.0
         */
        if (Math.abs(f) < FloatConsts.MIN_NORMAL
            &&  f != 0.0f ) {
            // 调整指数以创建低于正常值的双精度数
            // 用低于正常值的浮点数替换低于正常值的双指数
            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的对应方法进行转换
            return Double.toHexString(f);
    }

③ valueOf()

    /**
     * 获取float对象,接收String类型入参然后调用本类parseFloat()方法进行转换
     */
    public static Float valueOf(String s) throws NumberFormatException {
        return new Float(parseFloat(s));
    }

    /**
     * 获取float对象
     */
    public static Float valueOf(float f) {
        return new Float(f);
    }

④ parseFloat()

    /**
     * 将字符串转换为float类型,底层调用FloatingDecimal.parseFloat(s),
     * public Float(String s)构造器就是调用此方法进行操作的
     */
    public static float parseFloat(String s) throws NumberFormatException {
        return FloatingDecimal.parseFloat(s);
    }

⑤ isNaN()

    /**
     * 判断一个float值是否是NAN(NAN的值不等于NAN的:
     * 所有的无穷值都不相等,所以值和值本身比较若不相等则是true,
     * 这里的不等指的是值的不等)
     */
    public static boolean isNaN(float v) {
        return (v != v);
    }

    /**
     * 判断一个float值是否是NAN,调用静态isNaN()方法进行操作;
     */
    public boolean isNaN() {
        return isNaN(value);
    }

⑥ isInfinite()

    /**
     * 有限判断,只与正无穷或负无穷进行比较,满足其中一个条件即为有限
     */
    public static boolean isInfinite(float v) {
        return (v == POSITIVE_INFINITY) || (v == NEGATIVE_INFINITY);
    }
    
    /**
     * 有限判断,调用静态isInfinite()方法
     */
    public boolean isInfinite() {
        return isInfinite(value);
    }

⑦ isFinite()

    /**
     * 判断是否超出范围
     * 最大值为public static final float MAX_VALUE = 3.4028235E38F;
     */
     public static boolean isFinite(float f) {
        return Math.abs(f) <= FloatConsts.MAX_VALUE;
     }

⑧ 来自于Number继承类的方法实现

    /**
     * 将当前对象强转为byte,继承自Number方法
     */
    public byte byteValue() {
        return (byte)value;
    }

    /**
     * 将当前对象强转为short,继承自Number方法
     */
    public short shortValue() {
        return (short)value;
    }

    /**
     * 将当前对象强转为int,继承自Number方法
     */
    public int intValue() {
        return (int)value;
    }

    /**
     * 将当前对象强转为long,继承自Number方法
     */
    public long longValue() {
        return (long)value;
    }

    /**
     * 获取float对象的float值,继承自Number方法
     */
    public float floatValue() {
        return value;
    }

    /**
     * 将当前对象强转为double,继承自Number方法
     */
    public double doubleValue() {
        return (double)value;
    }

⑨ hashCode() 与 equals()

    /**
     * hashCode调用静态的hashCode方法
     */
    @Override
    public int hashCode() {
        return Float.hashCode(value);
    }

    /**
     * hashCode底层调用floatToIntBits()方法进行处理
     */
    public static int hashCode(float value) {
        return floatToIntBits(value);
    }
    
    _______________________________________
    
    /**
     * 判断是不是同一类型且两个对象的值是否一致
     */
    public boolean equals(Object obj) {
        return (obj instanceof Float)
               && (floatToIntBits(((Float)obj).value) == 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;
    }
____________________________________________________
    /**
     * floatToRawIntBits是一个本地方法,该方法主要是将一个
     * 浮点数转成IEEE 754标准的二进制形式对应的整型数
     */
    public static native int floatToRawIntBits(float value);
____________________________________________________
    /**
     * 将长bit换算成float值, native
     */
    public static native float intBitsToFloat(int bits);
____________________________________________________
    /**
     * 比较两个float的值进行比较,调用静态的compare()方法
     */    
    public int compareTo(Float anotherFloat) {
        return Float.compare(value, anotherFloat.value);
    }

    /**
     * 比较float值的核心逻辑
     */
    public static int compare(float f1, float f2) {
        // 先根据实际的float值进行判断
        if (f1 < f2)
            return -1;           
        if (f1 > f2)
            return 1;            

        // 因为可能有NaNs,所以不能直接比较thisBits与anotherBits的差值。
        // 调用floatToIntBits获取两个float对象的IEEE 754码然后进行比较
        int thisBits    = Float.floatToIntBits(f1);
        int anotherBits = Float.floatToIntBits(f2);
        // 通过IEEE 754码进行比较,返回值逻辑与float实际值比较相同
        return (thisBits == anotherBits ?  0 : (thisBits < anotherBits ? -1 : 1));                         
    }
___________________________________________________
    /**
     * 求和操作
     */
    public static float sum(float a, float b) {
        return a + b;
    }

    /**
     * 获取两个float值中的最大值,调用Math.max获取
     */
    public static float max(float a, float b) {
        return Math.max(a, b);
    }

    /**
     * 获取两个float值中的最小值,调用Math.max获取
     */
    public static float min(float a, float b) {
        return Math.min(a, b);
    }

5️⃣总结

  1. 方法中大量使用了重载
  2. 多数方法都是用到了IEEE 754码
  3. 大部分逻辑与double类一致,在学习这两个类源码的时候可以对比着进行学习;

相关文章

网友评论

      本文标题:9 java.lang.Float

      本文链接:https://www.haomeiwen.com/subject/kmshoftx.html