JDK源码解析---Double

1.概述

Double类是基本类型double的包装类。double 双精度浮点数在内存内占 8 个字节,用 64 位二进制描述。

2.类图

在这里插入图片描述

继承了Number类,可以用于数字类型的一系列转换

实现了Comparable接口,可以用于比较

实现了序列化接口,用于序列化和反序列

3.属性

  1. 静态常量,可直接通过类名.来调用
public static final double POSITIVE_INFINITY = 1.0 / 0.0;//正无穷
public static final double NEGATIVE_INFINITY = -1.0 / 0.0;//负无穷
public static final double NaN = 0.0d / 0.0;//double类型的非数值型
public static final double MAX_VALUE = 0x1.fffffffffffffP+1023;//double类型的非数值型
public static final double MIN_NORMAL = 0x1.0p-1022;//标准化的最小值
public static final double MIN_VALUE = 0x0.0000000000001P-1022;//double 类型数据能够保持的最小正非零值的常量。
public static final int MAX_EXPONENT = 1023;//指数真值的有效的最大值
public static final int MIN_EXPONENT = -1022;//指数真值的有效的最小值
public static final int SIZE = 64;//用秦以二进制补码形式表示 double 值的比特位数
public static final int BYTES = SIZE / Byte.SIZE;//二进制补码形式表示 double 值的字节数
public static final Class<Double>   TYPE = (Class<Double>) Class.getPrimitiveClass("double");//基本类型 double 的 Class 实例。
  1. 私有变量
private final double value;//用来保存这个类包装的double的数值

4.构造方法

  1. Double(double value) 将double封装成Double对象
public Double(double value) {
    this.value = value;
}
  1. Double(String s) 将String解析成double,再将其封装成Double对象
public Double(String s) throws NumberFormatException {
    value = parseDouble(s);
}

5.常用方法

  1. toString/toHexString

    ​ 将double转为String输出

public static String toString(double d) {
    return FloatingDecimal.toJavaFormatString(d);
}
public String toString() {
    return toString(value);
}

​ 返回16进制字符串

public static String toHexString(double d) {
    /*
     * Modeled after the "a" conversion specifier in C99, section
     * 7.19.6.1; however, the output of this method is more
     * tightly specified.
     */
    if (!isFinite(d) ) 
        // For infinity and NaN, use the decimal output.
        return Double.toString(d);
    else {
        // Initialized to maximum size of output.
        StringBuilder answer = new StringBuilder(24);

        if (Math.copySign(1.0, d) == -1.0)    // value is negative,
            answer.append("-");                  // so append sign info

        answer.append("0x");

        d = Math.abs(d);

        if(d == 0.0) {
            answer.append("0.0p0");
        } else {
            boolean subnormal = (d < DoubleConsts.MIN_NORMAL);

            // Isolate significand bits and OR in a high-order bit
            // so that the string representation has a known
            // length.
            long signifBits = (Double.doubleToLongBits(d)
                               & DoubleConsts.SIGNIF_BIT_MASK) |
                0x1000000000000000L;

            // Subnormal values have a 0 implicit bit; normal
            // values have a 1 implicit bit.
            answer.append(subnormal ? "0." : "1.");

            // Isolate the low-order 13 digits of the hex
            // representation.  If all the digits are zero,
            // replace with a single 0; otherwise, remove all
            // trailing zeros.
            String signif = Long.toHexString(signifBits).substring(3,16);
            answer.append(signif.equals("0000000000000") ? // 13 zeros
                          "0":
                          signif.replaceFirst("0{1,12}$", ""));

            answer.append('p');
            // If the value is subnormal, use the E_min exponent
            // value for double; otherwise, extract and report d's
            // exponent (the representation of a subnormal uses
            // E_min -1).
            answer.append(subnormal ?
                          DoubleConsts.MIN_EXPONENT:
                          Math.getExponent(d));
        }
        return answer.toString();
    }
}
  1. valueOf

    1. public static Double valueOf(String s)

      将String解析成double,然后调用构造函数包装成Double返回

    public static Double valueOf(String s) throws NumberFormatException {
        return new Double(parseDouble(s));
    }
    

    ​ b. public static Double valueOf(double d)

    ​ 将double 封装成Double

    public static Double valueOf(double d) {
        return new Double(d);
    }
    
  2. isXXX

    1. public static boolean isNaN(double v)

      1. 只有传入的值为NaN才为true
      public static boolean isNaN(double v) {
          return (v != v);
      }
      
    2. public static boolean isInfinite(double v)

      1. 只有传入的值为正无穷或负无穷才为true
      public static boolean isInfinite(double v) {
          return (v == POSITIVE_INFINITY) || (v == NEGATIVE_INFINITY);
      }
      
    3. public static boolean isFinite(double d)

      1. 判断是不是在double的范围内
      public static boolean isFinite(double d) {
          return Math.abs(d) <= DoubleConsts.MAX_VALUE;
      }
      
    4. public boolean isNaN() 判断是不是NaN的实例方法

      1. 内部调用静态方法isNaN
      public boolean isNaN() {
          return isNaN(value);
      }
      
    5. public boolean isInfinite() 判断是不是正负无穷的实例方法

      1. 内部调用静态方法isInfinite
      public boolean isInfinite() {
          return isInfinite(value);
      }
      
  3. XXXValue

    1. public byte byteValue() 将value强转为byte
    2. public short shortValue() 将value强转为short
    3. public int intValue() 将value强转为int
    4. public long longValue() 将value强转为long
    5. public float floatValue() 将value强转为float
    6. public double doubleValue() 直接返回value
  4. hashCode

    1. public int hashCode() 实例方法 内部调用静态方法Double.hashCode(value);

      public int hashCode() {
          return Double.hashCode(value);
      }
      public static int hashCode(double value) {
          long bits = doubleToLongBits(value);
          return (int)(bits ^ (bits >>> 32)) 
      }
      
  5. equals

    public boolean equals(Object obj) {
        return (obj instanceof Double)
          // 比较转换后的long类型是否相同
               && (doubleToLongBits(((Double)obj).value) ==
                      doubleToLongBits(value));
    }double转换成long类型
    public static long doubleToLongBits(double value) {
        long result = doubleToRawLongBits(value);
        if ( ((result & DoubleConsts.EXP_BIT_MASK) ==
              DoubleConsts.EXP_BIT_MASK) &&
              (result & DoubleConsts.SIGNIF_BIT_MASK) != 0L)
             result = 0x7ff8000000000000L;
        return result;
    }
    public static native long doubleToRawLongBits(double value);
    
  6. compareTo

    1. 判断两个double变量值严格相等,一般会直接用double_x == double_y来做比较,这样做一般没有问题,但是如果本意是比较两个浮点数对象是否相同(double_x == double_y是比较两个对象值是否严格相同),对象相同和值严格相等是不一样的,原因是java遵循IEEE 754浮点数标准,在这个标准中规定NaN与任何值比较皆不等,如果double_x与double_y的值都是NaN,这个时候他们是相同的对象,但double_x == double_y会返回false。解决方法是,判断浮点数对象是否相同,要用Double.doubleToLongBits将double值转换过后再比较
    public int compareTo(Double anotherDouble) {
        return Double.compare(value, anotherDouble.value);
    }
    public static int compare(double d1, double d2) {
            if (d1 < d2)
                return -1;           // Neither val is NaN, thisVal is smaller
            if (d1 > d2)
                return 1;            // Neither val is NaN, thisVal is larger
    
            // 转换成long再比较是否相等
            long thisBits    = Double.doubleToLongBits(d1);
            long anotherBits = Double.doubleToLongBits(d2);
    
            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)
        }
    

在这里插入图片描述

这是一个例子 结果如下

在这里插入图片描述

直接比较NaN的话 是不相等。但是若封装成对象在比较则是相等的。

6.其他方法

public static double sum(double a, double b) {
    return a + b;
}
public static double max(double a, double b) {
    return Math.max(a, b);
}
public static double min(double a, double b) {
    return Math.min(a, b);
}

猜你喜欢

转载自blog.csdn.net/gongsenlin341/article/details/107555918
今日推荐