【问题标题】:Java decimal format wrong formattingJava十进制格式错误格式
【发布时间】:2015-04-22 12:43:20
【问题描述】:

代码是:

private static DecimalFormat amDF=new DecimalFormat("###,###,###,##0.00");
amDF.setDecimalFormatSymbols(dfs); <- this only sets decimal separator, it works fine
amDF.setMinimumFractionDigits(2);
amDF.setMaximumFractionDigits(2);

格式化前的值为 210103.6,格式化后的值应为:210.103,60,而不是 210.103,59。

为什么我会损失 0.01?

编辑#1:数字是浮点数类的实例

编辑 #2:numberOfDecimals = 2

【问题讨论】:

  • 你甚至没有显示正在格式化的数字的类型。
  • 被格式化的数字是float 还是double?我们需要这些信息。
  • 你好。谢谢您的回复。 number 是:浮点数
  • 另外,将DecimalFormat 定义为静态并不是一个好主意——它在历史上存在线程安全问题。但这并没有导致这个问题......
  • ..numberOfDecimals 的(当前)值是多少?

标签: java decimalformat


【解决方案1】:

在 java 中使用浮点数时,您会看到精度的限制。它的 32 位精度根本不足以满足您的用途。

https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html

float:float 数据类型是单精度 32 位 IEEE 754 浮点数。它的值范围超出了本次讨论的范围,但在 Java 语言规范的浮点类型、格式和值部分中指定。与 byte 和 short 的建议一样,如果您需要在大型浮点数数组中节省内存,请使用浮点数(而不是双精度数)。 这种数据类型不应该用于精确值,例如货币。为此,您需要使用 java.math.BigDecimal 类。

您可以通过将号码类型更改为双精度来演示问题。在这种情况下,您的 DecimalFormat.format() 输出正确的值,因为 double 具有足够的精度来保存您正在使用的数字。

    final DecimalFormat df = new DecimalFormat("###,###,###,##0.00");
    df.setMinimumFractionDigits(2);
    df.setMaximumFractionDigits(2);
    System.out.println(df.format(210103.6f));

=> 210.103,59

    final DecimalFormat df = new DecimalFormat("###,###,###,##0.00");
    df.setMinimumFractionDigits(2);
    df.setMaximumFractionDigits(2);
    System.out.println(df.format(210103.6d));

=> 210.103,60

【讨论】:

  • 是的,这是我在阅读了一些关于浮动的文字后同意的正确答案。正如所说的“这种数据类型不应该用于精确值,例如货币”。但是实际上在调试模式下的eclipse输出是错误的,这就是我感到困惑的原因。
【解决方案2】:

这是Expressions tab 在 Eclipse 中的有趣行为,我尝试在调试模式下运行简单代码:

public static void main( String[] args ) throws Exception
{
    float number = 210103.59f;

    System.out.println( number );

}

断点与System.out.printlnExpressions tab 一致,我看到的值与您完全相同,即210103.6

【讨论】:

  • 我同意,在这种情况下,表达式选项卡显示“错误”值:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-30
相关资源
最近更新 更多