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 解析不正确