美文网首页
8 java.lang.Double

8 java.lang.Double

作者: 十丈_红尘 | 来源:发表于2018-09-23 20:28 被阅读0次

    1️⃣类定义

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

    2️⃣属性

        /**
         * 正无穷 : 程序运行值为 Infinity(无穷)
         */
        public static final double POSITIVE_INFINITY = 1.0 / 0.0;
    
        /**
         * 负无穷 : 程序运行值为 -Infinity(负无穷)
         */
        public static final double NEGATIVE_INFINITY = -1.0 / 0.0;
    
        /**
         * 非数字的double变量运行值为 NaN
         */
        public static final double NaN = 0.0d / 0.0;
    
        /**
         * 最大值
         */
        public static final double MAX_VALUE = 0x1.fffffffffffffP+1023; // 1.7976931348623157e+308
    
        /**
         * 规约所能表示的最小值
         */
        public static final double MIN_NORMAL = 0x1.0p-1022; // 2.2250738585072014E-308
    
        /**
         * 最小正数值 
         */
        public static final double MIN_VALUE = 0x0.0000000000001P-1022; // 4.9e-324
    
        /**
         * 指数的最大值
         */
        public static final int MAX_EXPONENT = 1023;
    
        /**
         * 指数的最小值
         */
        public static final int MIN_EXPONENT = -1022;
    
        /**
         * 所占的位数(64位)
         */
        public static final int SIZE = 64;
    
        /**
         * 字节数8个字节 ,这里除的是Byte的静态变量Byte.SIZE大小是8
         */
        public static final int BYTES = SIZE / Byte.SIZE;
    
        /**
         * @SuppressWarnings("unchecked")表示对警告保持静默 
         * 获取Double的原始class对象
         */
        @SuppressWarnings("unchecked")
        public static final Class<Double>   TYPE = (Class<Double>) Class.getPrimitiveClass("double");
    
        /**
         * double对象中具体的double值,定义为final
         */
        private final double value;
        
        /**
         * 序列化
         */
        private static final long serialVersionUID = -9172774392245257468L;
    

    3️⃣构造器

        /**
         * 直接把double赋值给value属性
         */
        public Double(double value) {
            this.value = value;
        }
    
        /**
         * 将string转化为double,底层调用FloatingDecimal类的parseDouble()方法
         * 来解析双精度浮点小数,在parseDouble()方法内进行一通解析操作
         */
        public Double(String s) throws NumberFormatException {
            value = parseDouble(s);
        }
    

    4️⃣方法

    ① toString()

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

    ② toHexString()

        /**
         * 将double转为16进制的字符串
         */
        public static String toHexString(double d) {
            /*
             * 判断double是否是有限的,调用本类的isFinite()方法
             */
            if (!isFinite(d) )
                /*
                 * 如果不是有限的直接调用本类的静态toString()进行处理并返回
                 * 对于无穷大和NaN,使用十进制输出。
                 */
                return Double.toString(d);
            /*
             * 如果double是有限的则走此逻辑
             */
            else {
                // 初始化到输出的最大大小。
                StringBuilder answer = new StringBuilder(24);
                // 判断是正数还是负数
                if (Math.copySign(1.0, d) == -1.0)
                    // 如果是值是负数,则拼接符号"-"
                    answer.append("-");                  
                // 拼接16进制前缀
                answer.append("0x");
                
                d = Math.abs(d);
    
                if(d == 0.0) {
                    answer.append("0.0p0");
                } else {
                    boolean subnormal = (d < DoubleConsts.MIN_NORMAL);
    
                    // double格式化成 IEEE 754 浮点双精度格式
                    long signifBits = (Double.doubleToLongBits(d)
                                       & DoubleConsts.SIGNIF_BIT_MASK) |
                        0x1000000000000000L;
    
                    answer.append(subnormal ? "0." : "1.");
    
                    String signif = Long.toHexString(signifBits).substring(3,16);
                    answer.append(signif.equals("0000000000000") ? // 13 zeros
                                  "0":
                                  signif.replaceFirst("0{1,12}$", ""));
    
                    answer.append('p');
                    
                    answer.append(subnormal ?
                                  DoubleConsts.MIN_EXPONENT:
                                  Math.getExponent(d));
                }
                return answer.toString();
            }
        }
    

    ③ valueOf()

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

    ④ parseDouble()

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

    ⑤ isNaN()

        /**
         * 判断一个double值是否是NAN(NAN的值不等于NAN的:
         * 所有的无穷值都不相等,所以值和值本身比较若不相等则是true,
         * 这里的不等指的是值的不等
         */
        public static boolean isNaN(double v) {
            return (v != v);
        }
        
        /**
         * 判断一个double值是否是NAN,调用静态isNaN()方法进行操作;
         */
        public boolean isNaN() {
            return isNaN(value);
        }
    

    ⑥ isInfinite()

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

    ⑦ isFinite()

        /**
         * 判断是否超出范围
         * 最大值为public static final double MAX_VALUE = 1.7976931348623157E308D
         */
        public static boolean isFinite(double d) {
            return Math.abs(d) <= DoubleConsts.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,继承自Number方法
         */
        public float floatValue() {
            return (float)value;
        }
    
        /**
         * 获取double对象的double值,继承自Number方法
         */
        public double doubleValue() {
            return value;
        }
    

    ⑨ hashCode() 与 equals()

        /**
         * hashCode调用静态的hashCode方法
         */
        @Override
        public int hashCode() {
            return Double.hashCode(value);
        }
    
        /**
         * hashCode底层调用doubleToLongBits()方法,并对返回结果进行右移32位的操作
         * 其实就是IEEE 754码
         */
        public static int hashCode(double value) {
            long bits = doubleToLongBits(value);
            return (int)(bits ^ (bits >>> 32));
        }
    
        ____________________________________________
        
        /**
         * 主要就是判断IEEE 754码是否相等,
         * 这里说的相等与isNaN()的相等概念上室友区别的
         * 这里的相等意思是对象的相等
         */
        public boolean equals(Object obj) {
            return (obj instanceof Double)
                   && (doubleToLongBits(((Double)obj).value) ==
                          doubleToLongBits(value));
        }
    

    ⑩ 其他方法

        /**
         * 将double转换为IEEE 754码
         */
        public static long doubleToLongBits(double value) {
            long result = doubleToRawLongBits(value);
            // Check for NaN based on values of bit fields, maximum
            // exponent and nonzero significand.
            if ( ((result & DoubleConsts.EXP_BIT_MASK) ==
                  DoubleConsts.EXP_BIT_MASK) &&
                 (result & DoubleConsts.SIGNIF_BIT_MASK) != 0L)
                result = 0x7ff8000000000000L;
            return result;
        }
        ___________________________________________________
        /**
         * 将double值换算成原始的bit, native
         */
        public static native long doubleToRawLongBits(double value);
        ___________________________________________________
        /**
         * 将长bit换算成double值, native
         */    
        public static native double longBitsToDouble(long bits);
        ___________________________________________________
        /**
         * 比较两个double的值进行比较,调用静态的compare()方法
         */
        public int compareTo(Double anotherDouble) {
            return Double.compare(value, anotherDouble.value);
        }
    
        /**
         * 比较double值的核心逻辑
         */
        public static int compare(double d1, double d2) {
            // 先根据实际的double值进行判断
            if (d1 < d2)
                return -1;           
            if (d1 > d2)
                return 1;            
            
            // 因为可能有NaNs,所以不能直接使用double - torawlongbits。
            // 调用doubleToLongBits获取两个double对象的IEEE 754码然后进行比较
            long thisBits    = Double.doubleToLongBits(d1);
            long anotherBits = Double.doubleToLongBits(d2);
            // 通过IEEE 754码进行比较,返回值逻辑与double实际值比较相同
            return (thisBits == anotherBits ?  0 : (thisBits < anotherBits ? -1 : 1));                          
        }
        _________________________________________________
        /**
         * 求和操作
         */
        public static double sum(double a, double b) {
            return a + b;
        }
    
        /**
         * 获取两个double值中的最大值,调用Math.max获取
         */
        public static double max(double a, double b) {
            return Math.max(a, b);
        }
    
        /**
         * 获取两个double值中的最小值,调用Math.min获取
         */
        public static double min(double a, double b) {
            return Math.min(a, b);
        }
    

    补充 : 关于IEEE 754码请参考https://baike.baidu.com/item/IEEE%20754/3869922?fr=aladdin


    5️⃣总结

    1. 方法中大量使用了重载
    2. 多数方法都是用到了IEEE 754码

    相关文章

      网友评论

          本文标题:8 java.lang.Double

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