Java Double 类
最后修改时间:2025 年 4 月 13 日
java.lang.Double
类是原始 double
类型的包装类,提供用于处理双精度浮点数的实用方法。 它允许在原始 double
值和 Double
对象之间进行转换,从而使它们可以在集合、泛型和面向对象的编程环境中使用。
除了转换函数之外,Double
类还为数值运算提供有用的常量和方法。 它包括用于解析、比较和检查特殊浮点值(例如 NaN
(非数字) 和无穷大)的功能。 这些功能有助于确保处理浮点算术时的精度和正确性。
Double 类方法
Double
类提供了多个用于处理 double 值的静态和实例方法。 一些关键方法包括
parseDouble(String s)
- 将字符串转换为原始double
类型,对无效输入抛出NumberFormatException
。valueOf(double d)
- 返回一个Double
对象,表示指定的原始double
值。doubleValue()
- 从Double
对象中提取原始double
值。compare(Double d1, Double d2)
- 比较两个Double
对象,根据它们的相对值返回负数、零或正数。isNaN(double d)
- 确定给定的double
值是否为NaN
,它发生在未定义的数学运算中。
通过利用这些方法,Double
类促进了 Java 中无缝转换、比较和数值运算,从而确保了处理浮点数据时的可靠性。
创建 Double 对象
Double
类提供了多种方法来创建表示双精度浮点数的实例。 可以使用 valueOf
方法实例化对象,由于它具有缓存常用值的潜力,因此是首选方法。 此外,Java 的自动装箱机制在必要时自动将原始 double
值转换为 Double
对象。
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
。
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 (非数字): 表示未定义的结果,例如
0/0
或Infinity - Infinity
。 NaN 值会在计算中传播。 - 正无穷大: 当一个值超过最大的 double 值时发生,例如
1.0 / 0.0
。 - 负无穷大: 表示一个无限小的值,例如
-1.0 / 0.0
。
这些值遵循浮点算术中的特定规则。 涉及 NaN
的运算几乎总是导致 NaN
。 无穷大值在乘法或加法中表现如预期,但在除以另一个无穷大时可能会变为 NaN
。
通过利用特殊值及其相应的验证方法,开发人员可以有效地处理浮点计算中的边缘情况,并防止意外的数值错误。
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 } }
此示例演示了特殊的浮点值——NaN
、POSITIVE_INFINITY
和 NEGATIVE_INFINITY
——在 Java 中的行为。 它展示了如何使用 isNaN
和 isInfinite
检查这些值,并说明了它们如何在算术运算中传播,从而帮助开发人员有效地处理数值计算中的边缘情况。
比较 Double 值
由于浮点精度误差,比较 double
值需要特别小心。 使用 ==
的直接相等性检查在处理小数值时可能会产生意外的结果。 compare
和 compareTo
方法提供了可靠的比较机制,可以正确处理 NaN
和无穷大等特殊值。
浮点精度限制可能导致不准确的相等性检查。 为了确保正确的比较,请遵循以下最佳实践
- 使用
Double.compare(d1, d2)
: 此方法正确处理特殊值,例如NaN
和无穷大。 - 避免直接相等性检查 (
d1 == d2
): 微小的精度差异可能会导致不准确的结果。 - 使用容差进行近似相等性检查:
Math.abs(d1 - d2) < tolerance
考虑了小的浮点误差。 - 小心使用
NaN
: 任何涉及NaN
的比较都会返回意外的结果,因为NaN
是无序的。 - 使用
BigDecimal
进行精确的十进制比较: 与double
不同,BigDecimal
提供了精确的十进制算术,从而防止了舍入误差。 使用BigDecimal.compareTo
进行可靠的相等性检查。
对于需要精确十进制值的场景,例如财务计算,BigDecimal
是首选。 它避免了浮点不准确性,并允许控制比例和舍入行为,从而确保数值计算的正确性。
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
值和其他原始类型之间进行转换。 这些方法允许无缝的数据转换,但在将浮点数转换为整数类型时,重要的是要考虑潜在的精度损失。
常见的转换方法包括 intValue
、longValue
和 floatValue
。 转换为整数类型时,小数部分会被截断而不是舍入,这可能会导致预期值的差异。
转换 Double
值时,请考虑以下几点
- 截断与舍入: 将
double
转换为整数类型会删除小数部分,而不是舍入。 - 精度损失: 由于存储格式的差异,转换为
float
可能会引入轻微的精度误差。 - 溢出风险: 将大的
double
值转换为byte
或short
可能会导致意外的溢出行为。 - 十六进制表示:
toHexString()
方法提供了一种基于 16 的浮点格式,可用于调试或存储。
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_VALUE
、MIN_VALUE
和 MAX_EXPONENT
。
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 应用程序中使用浮点数至关重要。
作者
列出所有Java教程。