Java8中的RoundingMode.HALF_DOWN问题 [英] RoundingMode.HALF_DOWN issue in Java8

查看:1845
本文介绍了Java8中的RoundingMode.HALF_DOWN问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用的是jdk 1.8.0_45,我们的测试发现了一个错误。
当决定舍入的最后一个小数是5时,RoundingMode.HALF_DOWN与RoundingMode.HALF_UP的工作方式相同。

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.

我发现了RoundingMode.HALF_UP的相关问题,但是它们在更新40中得到修复。我还在oracle中添加了一个bug,但根据我的经验,它们确实没有响应。

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));
    }
}

实际结果:
向下舍入
10.5556
上涨
10.5556

Actual result: Round down 10.5556 Round up 10.5556

预期结果(以jdk 1.7获得):
下调
10.5555
汇总
10.5556

Expected result(obtain with jdk 1.7): Round down 10.5555 Round up 10.5556

推荐答案

似乎有意改变。 JDK 1.7的行为不正确。

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

问题是你只是不能代表数字 10.55555 使用 double 类型。它以IEEE二进制格式存储数据,因此当您将小数 10.55555 数字分配给 double 变量时,实际上获得可以用IEEE格式表示的最接近的值: 10.555550000000000210320649784989655017852783203125 。此数字大于 10.55555 ,因此在 HALF_DOWN 10.5556 c $ c> mode。

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.

您可以检查一些可以用二进制精确表示的数字。例如, 10.15625 10 + 5/32 ,因此 1010.00101 二进制)。此数字在 HALF_DOWN 模式中舍入为 10.1562 10.1563 HALF_UP 模式。

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.

如果要恢复旧行为,可以先将数字转换为 BigDecimal 使用 BigDecimal.valueOf 构造函数,将 double 转换为 BigDecimal ,使用 double 的规范字符串表示形式:

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

这篇关于Java8中的RoundingMode.HALF_DOWN问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆