ZetCode

Java Double 类

最后修改时间:2025 年 4 月 13 日

java.lang.Double 类是原始 double 类型的包装类,提供用于处理双精度浮点数的实用方法。 它允许在原始 double 值和 Double 对象之间进行转换,从而使它们可以在集合、泛型和面向对象的编程环境中使用。

除了转换函数之外,Double 类还为数值运算提供有用的常量和方法。 它包括用于解析、比较和检查特殊浮点值(例如 NaN (非数字) 和无穷大)的功能。 这些功能有助于确保处理浮点算术时的精度和正确性。

Double 类方法

Double 类提供了多个用于处理 double 值的静态和实例方法。 一些关键方法包括

通过利用这些方法,Double 类促进了 Java 中无缝转换、比较和数值运算,从而确保了处理浮点数据时的可靠性。

创建 Double 对象

Double 类提供了多种方法来创建表示双精度浮点数的实例。 可以使用 valueOf 方法实例化对象,由于它具有缓存常用值的潜力,因此是首选方法。 此外,Java 的自动装箱机制在必要时自动将原始 double 值转换为 Double 对象。

Main.java
package com.zetcode;

public class Main {

    public static void main(String[] args) {

        Double d1 = Double.valueOf(3.14159);
        Double d2 = Double.valueOf("3.14159");

        // Using autoboxing
        Double d3 = 3.14159;

        System.out.println("d1: " + d1);
        System.out.println("d2: " + d2);
        System.out.println("d3: " + d3);

        // Converting back to primitive
        double primitive = d1;
        System.out.println("Primitive value: " + primitive);
    }
}

此示例演示了创建 Double 对象的不同方法。 valueOf 方法通常是首选方法,因为它可能会重用现有实例而不是创建新实例。 自动装箱简化了转换,在需要时自动将原始 double 值包装到 Double 对象中,从而减少了手动对象创建。

解析 Double 值

parseDouble 方法将字符串转换为原始 double 类型。 valueOf 方法将字符串转换为 Double 对象。 两者都会对无效输入抛出 NumberFormatException

Main.java
package com.zetcode;

public class Main {

    public static void main(String[] args) {

        String numStr1 = "3.14159";
        String numStr2 = "-123.456";
        String invalidStr = "3.14.159";
        
        // Parsing to primitive double
        double d1 = Double.parseDouble(numStr1);
        double d2 = Double.parseDouble(numStr2);
        
        // Parsing to Double object
        Double dObj1 = Double.valueOf(numStr1);
        Double dObj2 = Double.valueOf(numStr2);
        
        System.out.println("d1: " + d1);
        System.out.println("d2: " + d2);
        System.out.println("dObj1: " + dObj1);
        System.out.println("dObj2: " + dObj2);
        
        try {
            double invalid = Double.parseDouble(invalidStr);
        } catch (NumberFormatException e) {
            System.out.println("Invalid number format: " + invalidStr);
        }
    }
}

此示例显示了如何将字符串解析为 double 值。 parseDouble 返回一个原始类型,而 valueOf 返回一个 Double 对象。 两种方法都会对格式错误的输入抛出异常。

特殊的 Double 值

特殊的浮点值是由某些数学运算产生的

这些值遵循浮点算术中的特定规则。 涉及 NaN 的运算几乎总是导致 NaN。 无穷大值在乘法或加法中表现如预期,但在除以另一个无穷大时可能会变为 NaN

通过利用特殊值及其相应的验证方法,开发人员可以有效地处理浮点计算中的边缘情况,并防止意外的数值错误。

Main.java
package com.zetcode;

public class Main {

    public static void main(String[] args) {

        double nanValue = Double.NaN;
        double posInf = Double.POSITIVE_INFINITY;
        double negInf = Double.NEGATIVE_INFINITY;
        
        System.out.println("NaN: " + nanValue);
        System.out.println("Positive Infinity: " + posInf);
        System.out.println("Negative Infinity: " + negInf);
        
        System.out.println("Is NaN? " + Double.isNaN(nanValue));
        System.out.println("Is Infinity? " + Double.isInfinite(posInf));
        
        // Operations with special values
        System.out.println("NaN + 1: " + (nanValue + 1)); // NaN propagates
        System.out.println("Infinity * 2: " + (posInf * 2)); // Still infinity
        System.out.println("Infinity / Infinity: " + (posInf / posInf)); // Results in NaN
    }
}

此示例演示了特殊的浮点值——NaNPOSITIVE_INFINITYNEGATIVE_INFINITY——在 Java 中的行为。 它展示了如何使用 isNaNisInfinite 检查这些值,并说明了它们如何在算术运算中传播,从而帮助开发人员有效地处理数值计算中的边缘情况。

比较 Double 值

由于浮点精度误差,比较 double 值需要特别小心。 使用 == 的直接相等性检查在处理小数值时可能会产生意外的结果。 comparecompareTo 方法提供了可靠的比较机制,可以正确处理 NaN 和无穷大等特殊值。

浮点精度限制可能导致不准确的相等性检查。 为了确保正确的比较,请遵循以下最佳实践

对于需要精确十进制值的场景,例如财务计算,BigDecimal 是首选。 它避免了浮点不准确性,并允许控制比例和舍入行为,从而确保数值计算的正确性。

Main.java
package com.zetcode;

public class Main {

    public static void main(String[] args) {

        Double d1 = 1.23456;
        Double d2 = 1.23457;
        Double d3 = Double.NaN;
        Double d4 = Double.POSITIVE_INFINITY;
        
        // Using compareTo method (instance method)
        System.out.println("d1 compareTo d2: " + d1.compareTo(d2));
        System.out.println("d3 compareTo d1: " + d3.compareTo(d1));
        System.out.println("d4 compareTo d1: " + d4.compareTo(d1));
        
        // Using static compare method
        System.out.println("Compare d1 and d2: " + Double.compare(d1, d2));

        // Equality comparison with tolerance
        double tolerance = 0.0001;
        boolean nearlyEqual = Math.abs(d1 - d2) < tolerance;
        System.out.println("d1 nearly equals d2: " + nearlyEqual);
    }
}

此示例演示了在 Java 中比较浮点值的不同方法。 它展示了 compareTo 方法如何正确处理排序,即使使用 NaN 和无穷大等特殊值也是如此。 静态 Double.compare 方法提供了另一种比较 Double 实例的方法。 此外,该示例强调了在使用容差值检查近似相等性时,确保可靠比较的重要性,即使存在微小的浮点精度误差也是如此。

转换 Double 值

Double 类提供了多种方法来在 double 值和其他原始类型之间进行转换。 这些方法允许无缝的数据转换,但在将浮点数转换为整数类型时,重要的是要考虑潜在的精度损失。

常见的转换方法包括 intValuelongValuefloatValue。 转换为整数类型时,小数部分会被截断而不是舍入,这可能会导致预期值的差异。

转换 Double 值时,请考虑以下几点

Main.java
package com.zetcode;

public class Main {

    public static void main(String[] args) {

        Double d = 123.456789;
        
        // Converting to other primitive types
        int intVal = d.intValue();  // Truncates decimal part
        long longVal = d.longValue();
        float floatVal = d.floatValue(); // Potential precision loss
        byte byteVal = d.byteValue(); // Risk of overflow for large values
        short shortVal = d.shortValue();
        
        System.out.println("Original double: " + d);
        System.out.println("intValue: " + intVal);
        System.out.println("longValue: " + longVal);
        System.out.println("floatValue: " + floatVal);
        System.out.println("byteValue: " + byteVal);
        System.out.println("shortValue: " + shortVal);
        
        // Converting to String
        String strVal = d.toString();
        String hexStr = Double.toHexString(d);
        
        System.out.println("toString: " + strVal);
        System.out.println("toHexString: " + hexStr);
    }
}

此示例演示了安全高效的转换方法,重点介绍了开发人员在使用浮点数据时应考虑的潜在陷阱。

Double 常量和限制

Double 类提供了有用的常量,这些常量表示双精度浮点数的限制。 这些包括 MAX_VALUEMIN_VALUEMAX_EXPONENT

Main.java
package com.zetcode;

public class Main {

    public static void main(String[] args) {

        System.out.println("MAX_VALUE: " + Double.MAX_VALUE);
        System.out.println("MIN_VALUE: " + Double.MIN_VALUE);
        System.out.println("MIN_NORMAL: " + Double.MIN_NORMAL);
        System.out.println("MAX_EXPONENT: " + Double.MAX_EXPONENT);
        System.out.println("MIN_EXPONENT: " + Double.MIN_EXPONENT);
        System.out.println("SIZE: " + Double.SIZE + " bits");
        System.out.println("BYTES: " + Double.BYTES + " bytes");
        
        // Demonstrating overflow
        double max = Double.MAX_VALUE;
        System.out.println("MAX_VALUE * 2: " + (max * 2));
        
        // Demonstrating underflow
        double min = Double.MIN_VALUE;
        System.out.println("MIN_VALUE / 2: " + (min / 2));
    }
}

此示例显示了双精度浮点数的限制。 MAX_VALUE 是最大的有限正值,而 MIN_VALUE 是最小的正非零值。 溢出会导致无穷大,而下溢会导致零。

来源

Java Double 类文档

在本文中,我们介绍了 Java Double 类的基本方法和特性。 了解这些概念对于在 Java 应用程序中使用浮点数至关重要。

作者

我叫 Jan Bodnar,是一位敬业的程序员,在该领域拥有多年的经验。 我于 2007 年开始撰写编程文章,此后撰写了 1,400 多篇文章和八本电子书。 凭借超过八年的教学经验,我致力于分享我的知识并帮助他人掌握编程概念。

列出所有Java教程