JDK源码之Double类&Float类分析
一 概述
Double 类是基本类型double的包装类,fainl修饰,在对象中包装了一个基本类型double的值。Double继承了Number抽象类,具有了转化为基本double类型的功能。
此外,该类还提供了多个方法,可以将 double 类型与 String 类型相互转换,同时 还提供了处理 double 类型时比较常用的常量和方法。
二 Number类
三 源码解析
    // 表示正无穷大, 注意:浮点数才有无穷的概念,整数是没有的   1/0 会直接报错
    public static final double POSITIVE_INFINITY = 1.0 / 0.0;
    // 负无穷
    public static final double NEGATIVE_INFINITY = -1.0 / 0.0;
    // 表示非数 (即不是Number)
    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;
    // 位数
    public static final int SIZE = 64;
    // 字节数,  jdk1.8新增属性
    public static final int BYTES = SIZE / Byte.SIZE;
    // Double类型class实例
    @SuppressWarnings("unchecked")
    public static final Class<Double>   TYPE = (Class<Double>) Class.getPrimitiveClass("double");
    //转换为String
    public static String toString(double d) {
        return FloatingDecimal.toJavaFormatString(d);
    } //静态
    public String toString() {
        return toString(value);
    }  //实例,调用静态方法
    /**
     * 返回 double 参数的十六进制字符串表示形式
     */
    public static String toHexString(double d) {
        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 < Double.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 ?
                        Double.MIN_EXPONENT:
                        Math.getExponent(d));
            }
            return answer.toString();
        }
    }
    //根据参数返回新创建的Double对象,推荐使用这种构造器
    public static Double valueOf(String s) throws NumberFormatException {
        return new Double(parseDouble(s));
    }
    public static Double valueOf(double d) {
        return new Double(d);
    }
    //根据String返回double基本类型值
    public static double parseDouble(String s) throws NumberFormatException {
        return FloatingDecimal.parseDouble(s);
    }
    //判断 double是否是无穷大 (正无穷或者负无穷)
    public static boolean isInfinite(double v) {
        return (v == POSITIVE_INFINITY) || (v == NEGATIVE_INFINITY);
    }
    public boolean isInfinite() {
        return isInfinite(value);
    }
    //判断double是都是有限的
    public static boolean isFinite(double d) {
        return Math.abs(d) <= Double.MAX_VALUE;
    }
    // 此包装类的基本类型值
    private final double value;
    //构造器,jdk9被废弃,new这种方式在jdk9之后都不推荐使用了,改用valueOf形式API
    @Deprecated(since="9")
    public Double(double value) {
        this.value = value;
    }
    @Deprecated(since="9")
    public Double(String s) throws NumberFormatException {
        value = parseDouble(s);
    }
    //判断是否为NaN
    public boolean isNaN() {
        return isNaN(value);
    }
    public static boolean isNaN(double v) {
        return (v != v); //  NaN 与 NaN不相等
    }
    //基本类型转换
    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 (float)value;
    }
    public double doubleValue() {
        return value;
    }
    @Override
    public int hashCode() {
        return Double.hashCode(value);
    }
    // jdk8新增方法
    public static int hashCode(double value) {
        long bits = doubleToLongBits(value);
        return (int)(bits ^ (bits >>> 32));
    }
    public boolean equals(Object obj) {
        return (obj instanceof Double)
                && (doubleToLongBits(((Double)obj).value) ==
                doubleToLongBits(value));
    }
    //double 转 long
    public static long doubleToLongBits(double value) {
        if (!isNaN(value)) {
            return doubleToRawLongBits(value);
        }
        return 0x7ff8000000000000L;  // NaN 固定为此值
    }
    public static native long doubleToRawLongBits(double value);
    public static native double longBitsToDouble(long bits);
    //比较大小
    public int compareTo(Double anotherDouble) {
        return Double.compare(value, anotherDouble.value);
    }
    //比较两个double的大小
    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
        // Cannot use doubleToRawLongBits because of possibility of NaNs.
        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)
    }
    // 求和, jdk8新增运算
    public static double sum(double a, double b) {
        return a + b;
    }
    //返回两个double中比较大的那个数,jdk8新增运算
    public static double max(double a, double b) {
        return Math.max(a, b);
    }
    //返回两个double中比较小的那个数,jdk8新增运算
    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;
四 Float类
Float和Double的源码基本上是一样的,这里不再多记录,可以参考Double的代码解析
JDK源码之Double类&Float类分析的更多相关文章
- JDK源码学习之 集合实现类
		一.HashMap (1) 简介:java1.8版本之前HashMap的结构图如下: 数组的每个元素都是一个单链表的头节点,链表是用来解决冲突的,如果不同的key映射到了数组的同一位置处,就将其放入单 ... 
- JDK源码阅读(7):ConcurrentHashMap类阅读笔记
		ConcurrentHashMap public class ConcurrentHashMap<K,V> extends AbstractMap<K,V> implement ... 
- JDK源码之StringBuffer与StringBuilder类分析
		一 概述 StringBuffer类被 final 所修饰,不能被继承,StringBuffer继承了AbstractStringBuilder类, 是一个可变的字符序列,并且类中方法都有synchr ... 
- JDK源码阅读(4):HashMap类阅读笔记
		HashMap public class HashMap<K, V> extends AbstractMap<K, V> implements Map<K, V>, ... 
- JDK源码阅读(5):HashTable类阅读笔记
		HashTable public class Hashtable<K,V> extends Dictionary<K,V> implements Map<K,V>, ... 
- JDK源码分析之concurrent包(三) -- Future方式的实现
		上一篇我们基于JDK的源码对线程池ThreadPoolExecutor的实现做了分析,本篇来对Executor框架中另一种典型用法Future方式做源码解读.我们知道Future方式实现了带有返回值的 ... 
- Java中集合框架,Collection接口、Set接口、List接口、Map接口,已经常用的它们的实现类,简单的JDK源码分析底层实现
		(一)集合框架: Java语言的设计者对常用的数据结构和算法做了一些规范(接口)和实现(实现接口的类).所有抽象出来的数据结构和操作(算法)统称为集合框架. 程序员在具体应用的时候,不必考虑数据结构和 ... 
- JDK1.8源码(五)——java.util.ArrayList 类
		关于 JDK 的集合类的整体介绍可以看这张图,本篇博客我们不系统的介绍整个集合的构造,重点是介绍 ArrayList 类是如何实现的. 1.ArrayList 定义 ArrayList 是一个用数组实 ... 
- Mybatis源码解析(三) —— Mapper代理类的生成
		Mybatis源码解析(三) -- Mapper代理类的生成 在本系列第一篇文章已经讲述过在Mybatis-Spring项目中,是通过 MapperFactoryBean 的 getObject( ... 
随机推荐
- 金蝶handler中 collection 代码片段理解
			1,AtsOverTimeBillBatchEditHandler中collection的理解 SelectorItemCollection selectors = new SelectorItemC ... 
- Python实现截图功能
			Python实现截图功能 Windows环境下需要用到PIL库,使用pip安装PIL库: pip install Pillow 安装完成,截图方法代码: from PIL import ImageGr ... 
- Z字形变换 leetcode 6
			一.按行存储 1.解题思路 1.通过当前行的不断上下循环移动 2.将字符按序存放入vector中 3.最后再按行取出 2.代码及注释 class Solution { public: string c ... 
- 【题解】P4503 [CTSC2014]企鹅QQ(哈希)
			[题解]P4503 [CTSC2014]企鹅QQ(哈希) 考虑这样一种做法,将每个字符串的删去某个字符的新字符串的哈希值存下来,然后最后\(sort\)一遍双指针统计每个值相同的数的个数\(x\),这 ... 
- 【题解】多少个$1$(exBSGS)
			[题解]多少个\(1\)(exBSGS) 解方程: \[ \underbrace {1\dots1}_{n}\equiv k \mod m \] 其实就是 \[ \dfrac {10^n-1} {9} ... 
- 子网划分及NAT技术总结
			近段项目需要用到网络相关的知识,硬着头皮又回顾了一波,这里做一下记录. 一 分类的IP地址 我们使用的IP地址(IP V4)可以划分为A,B,C,D,E 5个类型,其中的D,为组播地址,E类地址为保留 ... 
- 「2018-12-02模拟赛」T3 约束排列 解题报告
			3.约束排列(place.pas/cpp/in/out) 问题描述: 给出 n 个互不相同的小写字母,表示出现的字符类型,以及 k 个约束关系: .....,表示 ai 必须出现在 bi 前面(ai, ... 
- ACM北大暑期课培训第六天
			今天讲了DFA,最小生成树以及最短路 DFA(接着昨天讲) 如何高效的构造前缀指针: 步骤为:根据深度一一求出每一个节点的前缀指针.对于当前节点,设他的父节点与他的边上的字符为Ch,如果他的父节点的前 ... 
- Cannot access org.springframework.context.ConfigurableApplicationContext
			Cannot access org.springframework.context.ConfigurableApplicationContext 需要将有问题的模块 删除 后重新导入 即可 IDEA ... 
- Java中的SPI扩展机制(有demo)
			参考连接:https://www.jianshu.com/p/3a3edbcd8f24 一.什么是SPI SPI ,全称为 Service Provider Interface,是一种服务发现机制.它 ... 
