JDK8 ---- java.lang.Double的理解

文章参考:

1 官方API文档

8java源码解析-Double

3 java源码分析(10)- Double(1)

4 [八]基础数据类型之Double详解

5 自己写的注释(对于一些重点且难得方法没有写注释。。。。扎心了)


package java.lang;

import sun.misc.FloatingDecimal;
import sun.misc.FpUtils;
import sun.misc.DoubleConsts;

/**

 Double类是基本类型double的封装类。一个Double对象包含了一个double类型的数值。


 这个类提供了很多静态或者是非晶态的方法来对double进行操作,例如
 将double转为String,或者是String转为double。

该类用final修饰,表明该类不可被继承和重写
 */
public final class Double extends Number implements Comparable<Double> {
    /**
    用一个常量表示double的无穷大
     */
    public static final double POSITIVE_INFINITY = 1.0 / 0.0;

    /**
    用一个常量表示double的无穷小
     */
    public static final double NEGATIVE_INFINITY = -1.0 / 0.0;

    /**
    该常量用于存储一个非数值类型。
     */
    public static final double NaN = 0.0d / 0.0;

    /**
    一个double类型常量存储double的有限最大值
     */
    public static final double MAX_VALUE = 0x1.fffffffffffffP+1023; // 1.7976931348623157e+308

    /**
    用一个常量来存储double可以表示的最小正数。
     */
    public static final double MIN_NORMAL = 0x1.0p-1022; // 2.2250738585072014E-308

    /**
    保持最小双精度类型的最小非零的常熟。
     */
    public static final double MIN_VALUE = 0x0.0000000000001P-1022; // 4.9e-324

    /**
    double变量可以拥有的最大指数值。
     */
    public static final int MAX_EXPONENT = 1023;

    /**
     double变量可以拥有的最小指数值。
     */
    public static final int MIN_EXPONENT = -1022;

    /**
    一个double类型变量为64位,即8个字节。
     */
    public static final int SIZE = 64;

    /**
    用于表示双精度值(double值)的字节数
     */
    public static final int BYTES = SIZE / Byte.SIZE;

    /**
    该类的实例表示基本类型double。
     */
    @SuppressWarnings("unchecked")
    public static final Class<Double>   TYPE = (Class<Double>) Class.getPrimitiveClass("double");

    /**
    将double参数转为字符串,不过其中所用的字符都是只ASCII码表示的字符。

     如果参数是NaN,那么就是返回字符串NaN。
   
     其他情况的话,调用toString()返回的结果是一个字符串,表示参数的符号和大小(绝对值)。
     如果符号为负数,则结果的第一个字符为'-'('\u002D');当然,如果是正数,那就没有符号。

     如果m是无穷大,则有字符"Infinity"表示,因此,Infinity结果为Infinity,
     负Infinity的结果为-Infinity。

     如果m大于或等于10的-3次方但小于10的次方,那么它表示为m的正数部分,十进制形式,没有前导0,
     后跟 '.''\u005Cu002E',后跟一个或多个十进制数字,表示m的小数部分。
    
    好了,一个示例比叙述好多了。。。
     public static void main(String[] args) {
        String dou = Double.toString(10.33);
        String dou2 = Double.toString(0.00000000000003);
        String dbou3 = Double.toString(-0.000000003);
        String dou4 = Double.toString(1000000000000000.3);
        String dou5 = Double.toString(-10000000000000.3);
        String dou6 = Double.toString(100000000);
        String dou7 = Double.toString(Double.NaN);
        String dou8 = Double.toString(10000);
        System.out.println(dou);
        System.out.println(dou2);
        System.out.println(dbou3);
        System.out.println(dou4);
        System.out.println(dou5);
        System.out.println(dou6);
        System.out.println(dou7);
        System.out.println(dou8);
        // 执行结果如下:
        // 10.33
        // 3.0E-14
        // -3.0E-9
        // 1.0000000000000002E15
        // -1.00000000000003E13
        // 1.0E8
        // NaN
        // 10000.0

    }
    从示例结果中可以看出,Double.toString方法会利用科学计数法将数值转为字符串

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

    /**
     将double以16进制的字符串表示。下面所提到的字符都是ASCII字符。
     
     如果Double是NaN,那么返回字符串就是NaN。
     */
    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) )
            // 对于NaN和无穷值,利用双精度进行输出。
            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();
        }
    }

    /**
     解析字符串成为Dobule对象,其中Double所存的值为double基本类型。
   
     如果s是null,那么将抛出NPE。

     头尾的空白字符将利用trim()方法过滤掉。
     */
    public static Double valueOf(String s) throws NumberFormatException {
        return new Double(parseDouble(s));
    }

    /**
     * Returns a {@code Double} instance representing the specified
     * {@code double} value.
     返回一个double参数的包装类,其实是调用构造方法。
     
     // 看不懂API文档中使用该valueOf()方法的优势。这方面要看看反编译的文档(需要JVM基础背景知识)
     */
    public static Double valueOf(double d) {
        return new Double(d);
    }

    /**
    
     如同valueOf()方法一样,返回字符串所表示的double数值。
    
    FloatingDecimal.parseDouble()方法难理解。
     */
    public static double parseDouble(String s) throws NumberFormatException {
        return FloatingDecimal.parseDouble(s);
    }

    /**
    用于判断参数v是不是NaN.
     */
    public static boolean isNaN(double v) {
        return (v != v);
    }

    /**
     如果输入的double为+Infinity,如果这个值为-Infinity。
     */
    public static boolean isInfinite(double v) {
        return (v == POSITIVE_INFINITY) || (v == NEGATIVE_INFINITY);
    }

    /**
     如果该参数是有穷值,那么就返回true,否则返回false(参数为NaN和infinity)
     */
    public static boolean isFinite(double d) {
        return Math.abs(d) <= DoubleConsts.MAX_VALUE;
    }

    /**
     * The value of the Double.
     *
     * @serial
     */
    private final double value;

    /**
    创建一个基础类型double值得封装类。
     */
    public Double(double value) {
        this.value = value;
    }

    /**
    利用Double构造函数将字符串解析成Double数值。
     */
    public Double(String s) throws NumberFormatException {
        value = parseDouble(s);
    }

    /**
    判断该Double值是不是NaN.
    示例:
    Double nan = Double.NAN;
    System.out.println(nan.isNaN());
     */
    public boolean isNaN() {
        return isNaN(value);
    }

    /**
    判官该值是不是无穷值
    示例:
    Double isplus = Double.POSITIVE_INFINITY;
    Double iscut = Double.NEGATIVE_INFINITY;
    System.out.println(isplus.isInfinite());
    System.out.println(iscut.isInfinite());
     */
    public boolean isInfinite() {
        return isInfinite(value);
    }

    /**
     将该Double值用字符串表示
     */
    public String toString() {
        return toString(value);
    }

    /**
     将Double值通过强制类型转换为byte类型值。
     */
    public byte byteValue() {
        return (byte)value;
    }

    /**
    将Double值通过强制类型转换为short类型值。
     */
    public short shortValue() {
        return (short)value;
    }

    /**
    将Double值通过强制类型转换为int类型值。
     */
    public int intValue() {
        return (int)value;
    }

    /**
    将Double值通过强制类型转换为long类型值。
     */
    public long longValue() {
        return (long)value;
    }

    /**
    将Double值通过强制类型转换为float类型值。
     */
    public float floatValue() {
        return (float)value;
    }

    /**
    将封装类Double值转为基本类型double值。
     */
    public double doubleValue() {
        return value;
    }

    /**
     * Returns a hash code for this {@code Double} object. The
     * result is the exclusive OR of the two halves of the
     * {@code long} integer bit representation, exactly as
     * produced by the method {@link #doubleToLongBits(double)}, of
     * the primitive {@code double} value represented by this
     * {@code Double} object. That is, the hash code is the value
     * of the expression:
     *
     * <blockquote>
     *  {@code (int)(v^(v>>>32))}
     * </blockquote>
     *
     * where {@code v} is defined by:
     *
     * <blockquote>
     *  {@code long v = Double.doubleToLongBits(this.doubleValue());}
     * </blockquote>
     *
     * @return  a {@code hash code} value for this object.
     */
    @Override
    public int hashCode() {
        return Double.hashCode(value);
    }

    /**
     返回double值的hash code,与double.hashcode()兼容。
     */
    public static int hashCode(double value) {
        long bits = doubleToLongBits(value);
        return (int)(bits ^ (bits >>> 32));
    }

    /**
     * Compares this object against the specified object.  The result
     * is {@code true} if and only if the argument is not
     * {@code null} and is a {@code Double} object that
     * represents a {@code double} that has the same value as the
     * {@code double} represented by this object. For this
     * purpose, two {@code double} values are considered to be
     * the same if and only if the method {@link
     * #doubleToLongBits(double)} returns the identical
     * {@code long} value when applied to each.
     *
     * <p>Note that in most cases, for two instances of class
     * {@code Double}, {@code d1} and {@code d2}, the
     * value of {@code d1.equals(d2)} is {@code true} if and
     * only if
     *
     * <blockquote>
     *  {@code d1.doubleValue() == d2.doubleValue()}
     * </blockquote>
     *
     * <p>also has the value {@code true}. However, there are two
     * exceptions:
     * <ul>
     * <li>If {@code d1} and {@code d2} both represent
     *     {@code Double.NaN}, then the {@code equals} method
     *     returns {@code true}, even though
     *     {@code Double.NaN==Double.NaN} has the value
     *     {@code false}.
     * <li>If {@code d1} represents {@code +0.0} while
     *     {@code d2} represents {@code -0.0}, or vice versa,
     *     the {@code equal} test has the value {@code false},
     *     even though {@code +0.0==-0.0} has the value {@code true}.
     * </ul>
     * This definition allows hash tables to operate properly.
     * @param   obj   the object to compare with.
     * @return  {@code true} if the objects are the same;
     *          {@code false} otherwise.
     * @see java.lang.Double#doubleToLongBits(double)
     */
    public boolean equals(Object obj) {
        return (obj instanceof Double)
               && (doubleToLongBits(((Double)obj).value) ==
                      doubleToLongBits(value));
    }

    /**
     * Returns a representation of the specified floating-point value
     * according to the IEEE 754 floating-point "double
     * format" bit layout.
     *
     * <p>Bit 63 (the bit that is selected by the mask
     * {@code 0x8000000000000000L}) represents the sign of the
     * floating-point number. Bits
     * 62-52 (the bits that are selected by the mask
     * {@code 0x7ff0000000000000L}) represent the exponent. Bits 51-0
     * (the bits that are selected by the mask
     * {@code 0x000fffffffffffffL}) represent the significand
     * (sometimes called the mantissa) of the floating-point number.
     *
     * <p>If the argument is positive infinity, the result is
     * {@code 0x7ff0000000000000L}.
     *
     * <p>If the argument is negative infinity, the result is
     * {@code 0xfff0000000000000L}.
     *
     * <p>If the argument is NaN, the result is
     * {@code 0x7ff8000000000000L}.
     *
     * <p>In all cases, the result is a {@code long} integer that, when
     * given to the {@link #longBitsToDouble(long)} method, will produce a
     * floating-point value the same as the argument to
     * {@code doubleToLongBits} (except all NaN values are
     * collapsed to a single "canonical" NaN value).
     *
     * @param   value   a {@code double} precision floating-point number.
     * @return the bits that represent the floating-point number.
     */
    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提供了对于指定值的表示形式的获取方法,者表示形式也就是一个64为的二进制位序列。

    根据IEEE 754浮点"双格式"位布局,返回指定浮点值得表示形式,保留非数字(NaN)值。

    第63位(比特位)(由掩码0x8000000000000000L选择的位)表示浮点数的符号。第62-52位(由掩码0x7ff0000000000000L选择的位)
    表示指数。第51-0位(由掩码0x000fffffffffffffL选择的位)表示浮点数的有效位数(有时称为尾数)。

    如果数值时正无穷,那么返回结果就是:0x7ff0000000000000L.
    如果数值是负无穷,那么返回结果就是:0xfff0000000000000L.

    如果参数是NaN,则结果返回的是实际NaN值得长整数。
     */
    public static native long doubleToRawLongBits(double value);

    /**
     * Returns the {@code double} value corresponding to a given
     * bit representation.
     * The argument is considered to be a representation of a
     * floating-point value according to the IEEE 754 floating-point
     * "double format" bit layout.
     *
     * <p>If the argument is {@code 0x7ff0000000000000L}, the result
     * is positive infinity.
     *
     * <p>If the argument is {@code 0xfff0000000000000L}, the result
     * is negative infinity.
     *
     * <p>If the argument is any value in the range
     * {@code 0x7ff0000000000001L} through
     * {@code 0x7fffffffffffffffL} or in the range
     * {@code 0xfff0000000000001L} through
     * {@code 0xffffffffffffffffL}, the result is a NaN.  No IEEE
     * 754 floating-point operation provided by Java can distinguish
     * between two NaN values of the same type with different bit
     * patterns.  Distinct values of NaN are only distinguishable by
     * use of the {@code Double.doubleToRawLongBits} method.
     *
     * <p>In all other cases, let <i>s</i>, <i>e</i>, and <i>m</i> be three
     * values that can be computed from the argument:
     *
     * <blockquote><pre>{@code
     * int s = ((bits >> 63) == 0) ? 1 : -1;
     * int e = (int)((bits >> 52) & 0x7ffL);
     * long m = (e == 0) ?
     *                 (bits & 0xfffffffffffffL) << 1 :
     *                 (bits & 0xfffffffffffffL) | 0x10000000000000L;
     * }</pre></blockquote>
     *
     * Then the floating-point result equals the value of the mathematical
     * expression <i>s</i>&middot;<i>m</i>&middot;2<sup><i>e</i>-1075</sup>.
     *
     * <p>Note that this method may not be able to return a
     * {@code double} NaN with exactly same bit pattern as the
     * {@code long} argument.  IEEE 754 distinguishes between two
     * kinds of NaNs, quiet NaNs and <i>signaling NaNs</i>.  The
     * differences between the two kinds of NaN are generally not
     * visible in Java.  Arithmetic operations on signaling NaNs turn
     * them into quiet NaNs with a different, but often similar, bit
     * pattern.  However, on some processors merely copying a
     * signaling NaN also performs that conversion.  In particular,
     * copying a signaling NaN to return it to the calling method
     * may perform this conversion.  So {@code longBitsToDouble}
     * may not be able to return a {@code double} with a
     * signaling NaN bit pattern.  Consequently, for some
     * {@code long} values,
     * {@code doubleToRawLongBits(longBitsToDouble(start))} may
     * <i>not</i> equal {@code start}.  Moreover, which
     * particular bit patterns represent signaling NaNs is platform
     * dependent; although all NaN bit patterns, quiet or signaling,
     * must be in the NaN range identified above.
     *
     * @param   bits   any {@code long} integer.
     * @return  the {@code double} floating-point value with the same
     *          bit pattern.
     */
    public static native double longBitsToDouble(long bits);

    /**
    比较两个double值的大小,返回值为 0 -1 1。
     */
    public int compareTo(Double anotherDouble) {
        return Double.compare(value, anotherDouble.value);
    }

    /**
     * Compares the two specified {@code double} values. The sign
     * of the integer value returned is the same as that of the
     * integer that would be returned by the call:
     比较两个double值的大小。该方法返回的大小的表示与调用调用:new Double(d1).compareTo(new Double(d2))方法
     返回的结果类似。
    
     */
    public static int compare(double d1, double d2) {
        if (d1 < d2)
            return -1;           // 两个数值都不是NaN,那么当前值比较小
        if (d1 > d2)
            return 1;            // 两个数值都不是NaN,那么当前值比较大

        // 不能使用doubleToRawLongBits()这个方法原因是:值可能为NaN。
        long thisBits    = Double.doubleToLongBits(d1);
        long anotherBits = Double.doubleToLongBits(d2);

        return (thisBits == anotherBits ?  0 : // 如果两个64位数值相等则返回0。
                (thisBits < anotherBits ? -1 : // (-0.0, 0.0) or (!NaN, NaN)
                 1));                          // (0.0, -0.0) or (NaN, !NaN)
    }

    /**
     为两个double值求和
     */
    public static double sum(double a, double b) {
        return a + b;
    }

    /**
    获取两个double值得最大值
     */
    public static double max(double a, double b) {
        return Math.max(a, b);
    }

    /**
     获取两个double值得最小值
     */
    public static double min(double a, double b) {
        return Math.min(a, b);
    }

    /** use serialVersionUID from JDK 1.0.2 for interoperability */
    private static final long serialVersionUID = -9172774392245257468L;
}

猜你喜欢

转载自blog.csdn.net/zuoyouzouzou/article/details/88640100
今日推荐