java roundingmode,Java8中的RoundingMode.HALF_DOWN问题

I am using jdk 1.8.0_45, and our tests discovered a bug in rouding.

RoundingMode.HALF_DOWN works the same as RoundingMode.HALF_UP when the last decimal that decide the rounding is 5.

I found related issues with RoundingMode.HALF_UP, but they are fixed in update 40. I also put a bug to the oracle, but from my experience they are really unresponsive.

package testjava8;

import java.math.RoundingMode;

import java.text.DecimalFormat;

public class Formatori {

public static void main(String[] args) {

DecimalFormat format = new DecimalFormat("#,##0.0000");

format.setRoundingMode(RoundingMode.HALF_DOWN);

Double toFormat = 10.55555;

System.out.println("Round down");

System.out.println(format.format(toFormat));

format.setRoundingMode(RoundingMode.HALF_UP);

toFormat = 10.55555;

System.out.println("Round up");

System.out.println(format.format(toFormat));

}

}

Actual result:

Round down

10.5556

Round up

10.5556

Expected result(obtain with jdk 1.7):

Round down

10.5555

Round up

10.5556

解决方案

Seems that it's intended change. The JDK 1.7 behavior was incorrect.

The problem is that you simply cannot represent the number 10.55555 using the double type. It stores the data in IEEE binary format, so when you assign the decimal 10.55555 number to the double variable, you actually get the closest value which can be represented in IEEE format: 10.555550000000000210320649784989655017852783203125. This number is bigger than 10.55555, so it's correctly rounded to 10.5556 in HALF_DOWN mode.

You can check some numbers which can be exactly represented in binary. For example, 10.15625 (which is 10 + 5/32, thus 1010.00101 in binary). This number is rounded to 10.1562 in HALF_DOWN mode and 10.1563 in HALF_UP mode.

If you want to restore the old behavior, you can first convert your number to BigDecimal using BigDecimal.valueOf constructor, which "translates a double into a BigDecimal, using the double's canonical string representation":

BigDecimal toFormat = BigDecimal.valueOf(10.55555);

System.out.println("Round down");

System.out.println(format.format(toFormat)); // 10.5555

format.setRoundingMode(RoundingMode.HALF_UP);

toFormat = BigDecimal.valueOf(10.55555);

System.out.println("Round up");

System.out.println(format.format(toFormat)); // 10.5556

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值