Java DecimalFormat HALF_EVEN模式舍入异常,是否为Bug?
这不是DecimalFormat的Bug,是浮点数精度问题
这并非DecimalFormat的Bug,问题根源在于浮点数的二进制存储精度限制:
- 浮点数表示的局限性
Java中的double类型遵循IEEE 754双精度标准,很多十进制小数无法被精确存储。你输入的1.575在内存中实际存储的是一个略小于1.575的值:1.5749999999999999555910790149937383830547332763671875。
当DecimalFormat以HALF_EVEN(银行家舍入)模式保留两位小数时,会基于这个实际存储的数值判断:由于该值的千分位实际小于0.005,因此会向下舍入得到1.57;而1.57501的存储值略大于1.575,千分位等效于超过0.005,所以会向上舍入为1.58。
- 解决方案
要避免这类精度问题,推荐使用BigDecimal来精确表示十进制数值:
Locale locale = new Locale("en", "US"); DecimalFormat currencyFormat = (DecimalFormat) NumberFormat.getNumberInstance(locale); currencyFormat.setMaximumFractionDigits(2); System.out.println(currencyFormat.getRoundingMode()); // 输出 HALF_EVEN // 用BigDecimal字符串构造方法精确表示1.575 System.out.println(currencyFormat.format(new BigDecimal("1.575"))); // 输出 1.58
内容的提问来源于stack exchange,提问作者Sey Zhao
相关产品推荐
相关产品推荐

