在java中格式化小数百分比会产生非常奇怪的行为
Posted
技术标签:
【中文标题】在java中格式化小数百分比会产生非常奇怪的行为【英文标题】:Format fractional percent in java yields very strange behaviour 【发布时间】:2012-02-13 16:58:52 【问题描述】:我正在尝试使用以下代码格式化百分比:
NumberFormat fmt = NumberFormat.getPercentInstance();
fmt.setRoundingMode(RoundingMode.HALF_UP);
fmt.setMinimumFractionDigits(0);
fmt.setMaximumFractionDigits(0);
System.out.println(fmt.format(0.145));
但是,我得到了一个非常奇怪的结果:
14%
将值 0.145 更改为其他值,例如 0.125 将正常工作,结果将符合预期
13%
有人可以解释一下吗?提前致谢
【问题讨论】:
【参考方案1】:这是由于double
中固有的舍入误差,导致0.145
被舍入到
0.1449999999999999900079927783735911361873149871826171875
如果您希望准确无误,请使用 BigDecimal
。
【讨论】:
出于好奇,为什么 0.125 不一样? 因为 0.125 可以精确地表示为二进制小数,因为它等于1/8
。【参考方案2】:
我认为这是浮动的实习生表示的结果。 (用二进制数表示的十进制数)。
您的 0.145 可能在内部表示为 0.144999999999...,因此舍入模式向下舍入。
【讨论】:
【参考方案3】:您应该阅读What Every Computer Scientist Should Know About Floating-Point Arithmetic,但基本上归结为 .145 不能以 IEEE 浮点数精确表示,因此被四舍五入到可以表示的最接近的值,恰好是略小于 0.145,因此当四舍五入为两位数时会向下舍入。
【讨论】:
以上是关于在java中格式化小数百分比会产生非常奇怪的行为的主要内容,如果未能解决你的问题,请参考以下文章
poi读取Excel时,如果单元格设置的是数字格式,如何解决整数与小数问题