【问题标题】:Print float with more decimal points [duplicate]打印带有更多小数点的浮点数[重复]
【发布时间】:2019-03-08 11:40:16
【问题描述】:

当我尝试打印带有更多小数点的浮点数时,我遇到了一种非常奇怪的行为。

Float price = Float.valueOf("1602.72");
System.out.println(price); //prints 1602.72
outputValue =   String.format("%.6f", price);
System.out.println(outputValue); //prints 1602.719971

我也使用了下面的代码,但得到了相同的结果

DecimalFormat df = new DecimalFormat("0.000000");
System.out.println(df.format(price)); //prints 1602.719971

我希望 outputValue 为 1602.720000(小数点后 6 位,带有额外的零)

【问题讨论】:

  • 那么,没有办法实现尾随零吗?
  • 与此密切相关,即使它是专门为 android 标记的:stackoverflow.com/q/35673034/4636715 所以,考虑使用BigDecimal
  • 所以没有办法在浮点数和十进制中做到这一点。我现在将 0 附加到字符串。谢谢

标签: java floating-point decimal


【解决方案1】:

float 是数字 ( 1 / 2 ^^ ? ) 的二进制表示
喜欢:

1/2^1 = 0.5, 
1/2^2 = 0.25, 
1/2^3 = 0.125, 
1/2^4 = 0.0625, ...  

通过将此二进制数相加以找到最接近的匹配来呈现结果。

【讨论】:

  • float 不是十进制数的二进制表示。 float 是数字的二进制表示。
【解决方案2】:

切勿在价格中使用浮点数或双精度数,浮点数和双精度数是近似值,请参阅:IEEE_754

改为查看BigDecimal

准确地说:使用浮点数或双精度数来表示小数是一个近似值。

【讨论】:

  • 所有数值算术充其量近似于实际算术。建议 BigDecimal 不是近似值而二进制浮点是近似值是不正确的。例如,BigDecimal 不能代表三分之一。对差异的正确表述是 BigDecimal 使用十进制基数,因此可以精确表示十进制数字,并且 BigDecimal 提供任意精度而不是 IEEE-754 的固定精度。
  • BigDecimal 表示十进制数,不是实数,因此不是近似值。问题是关于价格也是十进制的,所以我们可以用 BigDecimal 准确地表示价格。这个三明治多少钱? 6π$ :D 所以,是的,用 BigDecimal 表示实数将是一个近似值,但我的答案是面向上下文的,自然语言是面向上下文的……
  • 如果 BigDecimal 不是近似值,因为它代表十进制数,那么 floatdouble 不是近似值,因为它们代表二进制数。 BigDecimal 会出现与二进制浮点相同的错误:如前所述,BigDecimals 中的 1 除以 3 会产生数学上不正确的结果。这意味着,如果商家提供买二送一的优惠,BigDecimal 不能代表有效单价。
  • 好的,但是问题的作者要代表价格!所以,小数。
  • 如我的示例所述,价格并不总是十进制。十进制也不会自动解决货币计算中的所有问题。认为二进制浮点算术只是一个近似值而 BigDecimal 不是,这是一种误导。它们是两者的近似值,但它们是不同的近似值。由于您的回答表明一个是近似值,而另一个不是,因此具有误导性。
【解决方案3】:

这是因为floating point values are often imprecise for decimal fractions

基本上,由于浮点数使用 2 的负幂表示,因此某些十进制值很难准确表示(例如:如何将 0.3 写为 2 的幂和?)。

您可以尝试Float.valueOf("1602.720000")Double.valueOf("1602.72")(更好),但它们可能会有同样的问题。

更详细的解释请参考this的回答。

【讨论】:

  • 它们不是“非常难”,它们是不可能的。 :-)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-02
  • 2021-05-07
  • 2021-05-15
相关资源
最近更新 更多