3

我想知道如何将浮点数舍入为机器浮点数(例如double)。数字“0.01111116”不能用机器浮点数表示,在某些舍入模式下,这个数字应该表示为“0.011111159999999995”,但有一定的精度损失。但我不知道如何在 Java 中完成这个?所以我想知道设置舍入模式的API,以获得Java中机器浮点数的精确表示。谢谢!

4

3 回答 3

5

Java 规范没有提供任何方法来控制浮点舍入模式。使用四舍五入。

通常不可能安排浮点运算来产生数学上精确的结果,因此必须设计软件以容忍和调整错误,或者在非常特殊的情况下,通过格外小心来获得精确的结果。

于 2013-05-18T11:41:40.320 回答
1

如果您在程序的源代码中谈论文字0.01111116,Java 编译器会在编译时将其转换为二进制浮点表示。

如果您正在谈论(例如)包含字符“0.01111116”的字符串,如果/当您调用(例如)时,它将转换为二进制浮点表示Double.parseDouble(...)

无论哪种方式,转换都发生在幕后,您无法控制实际的舍入。但从某种意义上说,它是没有实际意义的。某些舍入发生在表示的性质中是固有的,并且结果通常是从数学角度可以得到的“最准确的”......给定您选择的浮点类型。

如果您真的希望转换使用不同的舍入/截断规则,您可以在事后执行此操作(例如舍入或截断转换后的值),或者您可以实现自己的字符串到浮点的转换方法。

您将无法更改 Java 编译器转换文字的方式。它是语言规范的一部分。


所以我想知道设置舍入模式的API,以获得Java中机器浮点数的精确表示。

对此还有另一种思考方式。

机器浮点数的精确表示是 32 位或 64 位二进制数据。double您可以通过以下几种方式将a 的位渲染为十六进制:

  • Double::doubleToLongBitsDouble::doubleToRawLongBits后跟Long::toHexString给出精确但无用的渲染,或
  • Double::toHexString给出十六进制浮点表示.

所有这些效果图都是 的精确(无舍入误差)表示double,但大多数读者不会理解它们。(“原始”版本最适合处理涉及变体 NaN 值的边缘情况。)

有等效的方法float

于 2013-05-18T02:42:20.933 回答
-1

尝试 commons-math3 Precision http://commons.apache.org/proper/commons-math/apidocs/org/apache/commons/math3/util/Precision.html

    double d = 0.1 + 0.2;
    System.out.println(d);
    d = Precision.round(d, 1);  <-- 1 decimal place
    System.out.println(d);

输出

0.30000000000000004
0.3
于 2013-05-18T02:43:50.550 回答