Java DecimalFormat.format保留2位小数JDK1.7与1.8舍入差异问题
JDK不同版本DecimalFormat舍入结果差异说明
差异产生的核心原因
该问题是JDK 1.7和1.8版本对DecimalFormat默认舍入规则的调整直接导致的:
- JDK 1.7及更早版本,
DecimalFormat默认使用ROUND_HALF_UP舍入模式,也就是日常常用的四舍五入规则:待舍弃部分的最高位等于5时,直接向前一位进1。0.045保留两位小数时,第三位小数是5,因此进1得到0.05。 - JDK 1.8及之后版本,
DecimalFormat默认改用ROUND_HALF_EVEN舍入模式,也叫银行家舍入法:待舍弃部分最高位等于5时,会判断保留位的最后一位是奇数还是偶数,奇数则进1,偶数则直接舍弃。0.045保留两位小数时,保留位的最后一位是4(偶数),因此直接舍弃后续的5,得到0.04。
额外补充:double类型的0.045本身无法被二进制浮点数精确存储,实际存储的数值略小于数学意义上的0.045,这个特性也会进一步放大不同舍入规则下的结果差异。
结果正确性判定
两种结果都符合对应版本的默认规则预期,不存在绝对的对错:
- 如果你的业务要求使用常规四舍五入规则,JDK 1.7的输出符合预期
- 如果你的业务要求使用银行家舍入法来降低累计误差,JDK 1.8的输出更符合预期
生产环境使用
DecimalFormat时,不要依赖JDK的默认舍入规则,必须主动调用setRoundingMode()方法显式指定业务需要的舍入模式,避免跨JDK版本部署时出现数据不一致的问题。
内容的提问来源于stack exchange,提问作者Vikas Kunte
相关产品推荐
相关产品推荐

