JDK源码-Double类

本文深入解析Java中的Double类,涵盖其构造方法、常量、方法及解决精度问题的策略。了解Double类如何处理浮点数,包括构造Double对象、常量定义、方法使用,以及如何避免精度丢失。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

上节我们介绍过JDK源码-Byte类
本节我们介绍Double类,float 单精度浮点数在内存内占 4 个字节,用 32 位二进制描述,double 双精度浮点数在内存内占 8 个字节,用 64 位二进制描述。


一、实现接口

Double类是基本类型double的包装类,继承了Number类,并且实现了Comparable接口

public final class Double extends Number implements Comparable<Double> 

二、构造方法

	//构造一个新分配的 Double 对象,它表示转换为 double 类型的参数。
  	public Double(double value) {
        this.value = value;
    }
    //构造一个新分配的 Double 对象,它表示 String 参数所指示的 double 值。
    public Double(String s) throws NumberFormatException {
        value = parseDouble(s);
    }

用来存放Double对象那double对应的值。

 private final double value;

如下创建Double 对象:
Double double1=new Double(5.456); //以 double 类型的变量作为参数创建 Double 对象
Double double2=new Double(“5.456”); //以 String 类型的变量作为参数创建 Double 对象


三、常用常量

这些常量都是static静态的,可直接使用 “类名.常量名” 进行使用

	//保持 double 类型的正无穷大的常量。
 	public static final double POSITIVE_INFINITY = 1.0 / 0.0;
 	//保持 double 类型的负无穷大的常量。
    public static final double NEGATIVE_INFINITY = -1.0 / 0.0;
    //保存 double 类型的非数字值的常量。
    public static final double NaN = 0.0d / 0.0;
    //表示 double 类型的最大正有限值的常量。
    public static final double MAX_VALUE = 0x1.fffffffffffffP+1023; // 1.7976931348623157e+308
    //标准化的最小值
    public static final double MIN_NORMAL = 0x1.0p-1022; // 2.2250738585072014E-308
    //表示 double 类型数据能够保持的最小正非零值的常量。
    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;
    //用秦以二进制补码形式表示 double 值的比特位数
    public static final int SIZE = 64;
    //二进制补码形式表示 double 值的字节数
    public static final int BYTES = SIZE / Byte.SIZE;
	//表示基本类型 double 的 Class 实例。
    @SuppressWarnings("unchecked")
    public static final Class<Double>   TYPE = (Class<Double>) Class.getPrimitiveClass("double");

四、常用方法

toXXXString 系列

	//静态方法
 	public static String toString(double d) {
        return FloatingDecimal.toJavaFormatString(d);
    }
    
    //实例方法内部调用  static String toString(double d)
	public String toString() {
        return toString(value);
    }
    
    //静态方法返回double参数的十六进制字符串表示形式API帮助文档中对于字符的转换有明确的规定,可以仔细研究下示例
    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 < DoubleConsts.MIN_NORMAL);
                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") ? "0":signif.replaceFirst("0{1,12}$", ""));
                answer.append('p');
                answer.append(subnormal ? DoubleConsts.MIN_EXPONENT: Math.getExponent(d));
            }
            return answer.toString();
        }
    }

valueOf(String s)

传入String类型字符串,通过parseDouble方法将字符串解析为double,创建一个Double对象返回,保存指定的 String 值的 Double 对象。

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

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

parseDouble(String s)

将数字字符串转换为 Double 数值

 	public static double parseDouble(String s) throws NumberFormatException {
        return FloatingDecimal.parseDouble(s);
    }

isNaN(double v)

	//如果指定的参数是一个非数字值,则返回 true,否则返回 false
	public static boolean isNaN(double v) {
        return (v != v);
    }
    //如果此 Double 值是一个非数字值,则返回 true,否则返回 false
    public boolean isNaN() {
        return isNaN(value);
    }

isInfinite和isFinite

	//判断double值的大小是否是无穷大,如果是则返回true;否则返回false。
 	public static boolean isInfinite(double v) {
        return (v == POSITIVE_INFINITY) || (v == NEGATIVE_INFINITY);
    }
	//判断是否是有限的浮点数,有限的true
    public static boolean isFinite(double d) {
        return Math.abs(d) <= DoubleConsts.MAX_VALUE;
    }

XXXValue系列

类似之前介绍的其他数值类型全部都是强转内部的 valuereturn (XXX)value;

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

equals(Object obj)

将此对象与指定对象比较当且仅当参数不是 null 而是 Double 对象,且表示的 Double 值与此对象表示的 double 值相同时,结果为 true

注意,在大多数情况下,对于 Double 类的两个实例 d1 和 d2,当且仅当d1.doubleValue() == d2.doubleValue() 为 true 时,d1.equals(d2) 的值才为 true
例外情况:
如果 d1 和 d2 都表示 Double.NaN,那么即使 Double.NaN == Double.NaN 值为 false,equals 方法也将返回 true
如果 d1 表示 +0.0 而 d2 表示 -0.0,或者相反,那么即使 +0.0==-0.0 值为 true,equals 测试也将返回 false

	public boolean equals(Object obj) {
        return (obj instanceof Double) && (doubleToLongBits(((Double)obj).value) ==doubleToLongBits(value));
    }

hashCode方法

	//实例方法依赖静态方法
 	@Override
    public int hashCode() {
        return Double.hashCode(value);
    }

	//静态方法获得一个value的hashcode值
    public static int hashCode(double value) {
        long bits = doubleToLongBits(value);
        return (int)(bits ^ (bits >>> 32));
    }

其他方法

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

五、总结

double会出现精度丢失问题:整数永远可以用二进制精确表示 ,但小数就不一定了
解决方案:
java中提供了一种类:BigDecimal,在平常的开发中使用java.math.BigDecimal类来进行精确计算。
在使用BigDecimal类来进行计算的时候,主要分为以下步骤:

  • 用float或者double变量构建BigDecimal对象。
  • 通过调用BigDecimal的加,减,乘,除等相应的方法进行算术运算。
  • 把BigDecimal对象转换成float,double,int等类型。

一般来说,可以使用BigDecimal的构造方法或者静态方法的valueOf()方法把基本类型的变量构建成BigDecimal对象。

	BigDecimal b1 = new BigDecimal(Double.toString(0.48)); 
 	BigDecimal b2 = BigDecimal.valueOf(0.48);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值