java - 在 Java 中使用 double 保持精度

标签 java floating-point double precision

public class doublePrecision {
    public static void main(String[] args) {

        double total = 0;
        total += 5.6;
        total += 5.8;
        System.out.println(total);
    }
}

以上代码打印:

11.399999999999

我怎样才能让它只打印(或能够用作)11.4?

最佳答案

正如其他人所提到的,您可能想要使用 BigDecimal类,如果你想有 11.4 的精确表示。

现在,稍微解释一下为什么会发生这种情况:

Java 中的 floatdouble 原始类型是 floating point数字,其中数字存储为分数和指数的二进制表示。

更具体地说,像 double 类型这样的 double 浮点值是 64 位值,其中:

  • 1 位表示符号(正或负)。
  • 11 位的指数。
  • 有效数字为 52 位(小数部分为二进制)。

这些部分组合起来产生一个值的 double 表示。

(来源:Wikipedia: Double precision)

有关如何在 Java 中处理浮点值的详细说明,请参阅 Section 4.2.3: Floating-Point Types, Formats, and Values Java 语言规范。

bytecharintlong 类型为fixed-point数字,它们是数字的精确表示。与定点数不同, float 有时(可以安全地假设“大部分时间”)无法返回数字的精确表示。这就是为什么你最终得到 11.399999999999 作为 5.6 + 5.8 的结果的原因。

当需要一个精确的值(例如 1.5 或 150.1005)时,您需要使用其中一种能够精确表示数字的定点类型。

正如已经多次提到的,Java 有一个 BigDecimal将处理非常大的数字和非常小的数字的类。

来自 BigDecimal 类的 Java API 引用:

Immutable, arbitrary-precision signed decimal numbers. A BigDecimal consists of an arbitrary precision integer unscaled value and a 32-bit integer scale. If zero or positive, the scale is the number of digits to the right of the decimal point. If negative, the unscaled value of the number is multiplied by ten to the power of the negation of the scale. The value of the number represented by the BigDecimal is therefore (unscaledValue × 10^-scale).

在 Stack Overflow 上存在许多与 float 及其精度有关的问题。以下是可能感兴趣的相关问题列表:

如果您真的想深入了解 float 的基本细节,请查看 What Every Computer Scientist Should Know About Floating-Point Arithmetic .

关于java - 在 Java 中使用 double 保持精度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/322749/

相关文章:

java - JOOQ 外键概念缺陷?

c++ - 可以使用一个指针来匹配 Python 中 float 变量的 int 值吗?

java - 四舍五入到最接近的 0.05 值的问题

java - 为什么在 Spring 应用程序中应避免使用 getBean()

JUnit 测试类中未分配 Java 变量

java - 需要 Swing 布局方面的帮助

c++ - 错误 "cannot convert ' float '到 'float...' ..."

java - Java 中的 `x > 0` 和 `x > 0.0D` 之间有什么区别吗?

java - 打印不同长度的数组

Java 将一系列分数相加