JDK源码(9)-Double、Float

简介: JDK源码(9)-Double、Float

一、概述

 

这个千篇一律,Double是对基本数据类型double的包装,里面包含了double类型的字段。这个类也提供了一些将String和double转换为Double的方法,还有一些处理double的方法。

作者是:

* @author  Lee Boynton
 * @author  Arthur van Hoff
 * @author  Joseph D. Darcy
 * @since JDK1.0

image.gif

二、属性

提供了很多属性值,如下:

image.gif编辑

正无穷:POSITIVE_INFINITY:Double.longBitsToDouble(0x7ff0000000000000L)

负无穷:NEGATIVE_INFINITY:Double.longBitsToDouble(0xfff0000000000000L)

非数字:Not-a-Number (NaN):Double.longBitsToDouble(0x7ff8000000000000L)

最大值:MAX_VALUE:Double.longBitsToDouble(0x7fefffffffffffffL)

单精度最小值:MIN_NORMAL:Double.longBitsToDouble(0x0010000000000000L)

双精度最小值:MIN_VALUE:Double.longBitsToDouble(0x1L)

最大指数:MAX_EXPONENT:1023

最小指数:MIN_EXPONENT:-1022

三、主要方法

toString:很简单

toHexString:将double转换为16进制字符串,就是StringBuilder的字符串拼接:

public static String toHexString(double d) {
        if (!isFinite(d) )
            //如果是NaN或是无穷,直接返回对应的字符串形式
            return Double.toString(d);
        else {
            //初始化最大长度:24
            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();
        }
    }

image.gif

判断是否为NaN

public static boolean isNaN(double v) {
        return (v != v);
    }

image.gif

判断是否无限

public static boolean isInfinite(double v) {
        return (v == POSITIVE_INFINITY) || (v == NEGATIVE_INFINITY);
    }

image.gif

判断是否有限

public static boolean isFinite(double d) {
        return Math.abs(d) <= DoubleConsts.MAX_VALUE;
    }

image.gif

haseCode被重写了

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

image.gif

doubleToLongBits:很多方法中用到了这个方法,理解为将double转换为64位的long即可

    • 根据IEEE 754浮点“双格式”位布局返回指定浮点值的表示。
    • 位63(由掩码0x8000000000000000L选择的位)表示浮点数的符号。 位62-52(由掩码0x7ff0000000000000L选择的位)表示指数。 位51-0(由掩码0x000fffffffffffffL选择的位)表示浮点数的有效数(有时称为尾数)。
    • 如果参数为无穷大,则结果为0x7ff0000000000000L
    • 如果参数为负无穷大,则结果为0xfff0000000000000L
    • 如果参数是NaN,结果是0x7ff8000000000000L
    • 在所有情况下,结果是long整数,当给予longBitsToDouble(long)方法时,将产生与doubleToLongBits的参数相同的浮点值(除了所有NaN值都被折叠为单个“规范”NaN值)。
    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;
        }

    image.gif

    doubleToRawLongBits:与doubleToLongBits方法不同, doubleToRawLongBits不会将编码NaN的所有位模式折叠到单个“规范”NaN值。是一个native的方法了。

    public static native long doubleToRawLongBits(double value);

    image.gif

    compare:重写比较,注意Double.NaN返回是0

    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)
        }

    image.gif

    还有三个运算方法

    sum,max,min

    image.gif

    三、Float

    Float与Double非常类似,不再单独讲解

    相关文章
    |
    4天前
    |
    安全 前端开发 Java
    JDK源码级别彻底剖析JVM类加载机制
    JDK源码级别彻底剖析JVM类加载机制
    |
    4天前
    |
    缓存 Dubbo Java
    趁同事上厕所的时间,看完了 Dubbo SPI 的源码,瞬间觉得 JDK SPI 不香了
    趁同事上厕所的时间,看完了 Dubbo SPI 的源码,瞬间觉得 JDK SPI 不香了
    |
    4天前
    |
    存储 Java
    百度搜索:蓝易云【Java语言之float、double内存存储方式】
    由于使用IEEE 754标准进行存储,float和double类型可以表示非常大或非常小的浮点数,并且具有一定的精度。然而,由于浮点数的特性,它们在进行精确计算时可能会存在舍入误差。在编写Java程序时,需要注意使
    61 0
    |
    4天前
    |
    缓存 Java Spring
    Spring 源码阅读 66:基于 JDK 的 AOP 代理如何获取拦截器链(4)- 将 Advice 封装为拦截器
    【1月更文挑战第1天】本文分析了 Advice 被封装成 MethodInterceptor 的过程,Spring AOP 用到的五种 Advice 中,有些本身就是 MethodInterceptor 的实现类,而有些需要通过适配器的封装。
    44 0
    |
    4天前
    |
    C#
    C# 字节数组与INT16,float,double之间相互转换,字符数组与字符串相互转换,
    C# 字节数组与INT16,float,double之间相互转换,字符数组与字符串相互转换,
    83 1
    |
    4天前
    |
    算法 Java 索引
    【数据结构与算法】4、双向链表(学习 jdk 的 LinkedList 部分源码)
    【数据结构与算法】4、双向链表(学习 jdk 的 LinkedList 部分源码)
    35 0
    |
    4天前
    |
    设计模式 Java
    根据JDK源码Calendar来看工厂模式和建造者模式
    根据JDK源码Calendar来看工厂模式和建造者模式
    |
    4天前
    |
    Java Linux iOS开发
    Spring5源码(27)-静态代理模式和JDK、CGLIB动态代理
    Spring5源码(27)-静态代理模式和JDK、CGLIB动态代理
    24 0
    |
    4天前
    |
    XML Java 数据格式
    Spring 源码阅读 70:基于 JDK 的 AOP 代理拦截器链执行(4)- 容易被忽略的 ExposeInvocationInterceptor
    【1月更文挑战第5天】本文分析了 Spring AOP 拦截器链中的一个特殊拦截器 ExposeInvocationInterceptor 的注册的时机以及它的作用。至此,基于 JDK 的 AOP 代理拦截器链执行的逻辑就分析完了。
    450 0
    |
    4天前
    |
    Java 索引 Spring
    Spring 源码阅读 69:基于 JDK 的 AOP 代理拦截器链执行(3)- MethodInterceptor 分析
    【1月更文挑战第4天】本文详细分析了 Spring AOP 中五种增强类型对应的拦截器中增强方法的执行逻辑,结合上一篇中分析的 ReflectiveMethodInvocation 中proceed方法的执行逻辑,就组成了完整的拦截器链递归调用的逻辑。
    35 0

    热门文章

    最新文章