NumberFormat 不喜欢超过 340 位小数

Posted

技术标签:

【中文标题】NumberFormat 不喜欢超过 340 位小数【英文标题】:NumberFormat doesn't like more than 340 decimal places 【发布时间】:2017-03-12 20:52:15 【问题描述】:

我想在 Java 中格式化具有一定小数位数的双精度数。我的代码目前如下所示:

    final NumberFormat format = NumberFormat.getInstance();
    format.setMinimumFractionDigits(decimalPlaces);
    format.setMaximumFractionDigits(decimalPlaces);
    format.setGroupingUsed(false);
    String s = format.format(value);

但是当decimalPlaces 超过 340 时,这个方法只打印 340 位而忽略其余的。有没有办法解决这个限制?

特别是在我的情况下,它们都是 0(并且在某个点之后可能会是任何数字,因为精度不是那么高)但对我来说,函数只是默默地忽略我想要的而不是抛出,这似乎是错误的一个例外什么的。

是的,我知道 double 实际上不能保存那么多小数位,但 int 根本不能保存任何小数位也是事实,但我可以用一些打印它。

【问题讨论】:

你能包括你对“decimalPlaces”的价值是什么 这是一个作业。我们必须制作一个简单的命令行计算器,在其中一个测试中有一个 0 结果,必须打印 500 个小数位(全为零)。这种方法在 340 处将它们切断,甚至没有显示任何错误。 我很确定我们不应该制作自己的打印功能。 【参考方案1】:

setMinimumFractionDigits 的文档包含这样的声明:

具体的子类可能会对该值施加一个上限,以适应被格式化的数字类型。

NumberFormat.getInstance 返回的子类很可能是DecimalFormat,它在JavaDocs 中告诉我们

对于除 BigInteger 和 BigDecimal 对象以外的格式化数字,使用 newValue 和 340 中的较低值。负输入值替换为 0。

因此,为了解决您的问题,请在格式化之前将您的号码转换为 BigDecimal

【讨论】:

我现在在文档中发现了这一点,但是有没有更简单的方法可以做到这一点? 我认为这很简单——这是一个相对合理的限制。如果您不使用可以以如此精确度表示数字的数据类型,则很少需要打印那么多小数位... 好吧,我想这很简单,但相当浪费资源。这是我们甚至还没有学习课程的时候的作业。我认为我们应该用 printf 或其他东西来做,但对我来说,将数字格式化为字符串以便 printf 再次解析它似乎更糟糕。 不要担心“相当浪费资源”。这些位被重复使用。【参考方案2】:

在 double 的情况下,值会被截断。使用/声明值作为BigDecimal

试试这个示例代码:

    final NumberFormat format = NumberFormat.getInstance();
    format.setMinimumFractionDigits(355);
    format.setMaximumFractionDigits(400);
    format.setGroupingUsed(false);
    System.out.println(format.getMinimumFractionDigits());
    BigDecimal bd=new BigDecimal(10L);
    String s = format.format(bd);
    System.out.println(s.length());
    System.out.println(s);

【讨论】:

以上是关于NumberFormat 不喜欢超过 340 位小数的主要内容,如果未能解决你的问题,请参考以下文章

在 Excel VBA 中使用 .NumberFormat 格式化小数位

Java `NumberFormat` 假定数字类型不正确

一位小公司CTO的成长历程

Java 中非默认语言环境的 NumberFormat 解析不正确

excel 互操作:NumberFormat #,##0.000 不显示预期结果

如何设置约束,以使视图的宽度至少等于某个宽度时为0