gpt4 book ai didi

java - Java RoundingMode.HALF_EVEN 是错误吗?

转载 作者:搜寻专家 更新时间:2023-11-01 02:04:21 25 4
gpt4 key购买 nike

当我用HALF_EVEN模式对双数取整时,发现一个问题,不知道是不是JDK的bug?请看下面的代码:

public static void main(String[] args) {
RoundingMode mode = RoundingMode.HALF_EVEN;
for (int i = 10; i < 100; i++) {
double d = i + 0.55;
int scale = 1;
process(d, scale++, mode);

d = i + 0.555;
process(d, scale++, mode);

d = i + 0.5555;
process(d, scale++, mode);

d = i + 0.55555;
process(d, scale++, mode);
System.out.println("\n");
}
}

private static void process(double d, int scale, RoundingMode roundingMode) {
BigDecimal b = new BigDecimal(d).setScale(scale, roundingMode);
System.out.println(d + " -> " + b);
}

我期望输出:

10.55 -> 10.6
10.555 -> 10.56
10.5555 -> 10.556
10.55555 -> 10.5556


11.55 -> 11.6
11.555 -> 11.56
11.5555 -> 11.556
11.55555 -> 11.5556

.....

但实际上,它输出的数据如下:

10.55 -> 10.6
10.555 -> 10.55
10.5555 -> 10.556
10.55555 -> 10.5556


11.55 -> 11.6
11.555 -> 11.55
11.5555 -> 11.556
11.55555 -> 11.5556
....

30.55 -> 30.6
30.555 -> 30.55
30.5555 -> 30.555
30.55555 -> 30.5556



31.55 -> 31.6
31.555 -> 31.55
31.5555 -> 31.555
31.55555 -> 31.5556



32.55 -> 32.5
32.555 -> 32.55
32.5555 -> 32.556
32.55555 -> 32.5555



33.55 -> 33.5
33.555 -> 33.55
33.5555 -> 33.556
33.55555 -> 33.5555

.........

62.55 -> 62.5
62.555 -> 62.55
62.5555 -> 62.556
62.55555 -> 62.5555



63.55 -> 63.5
63.555 -> 63.55
63.5555 -> 63.556
63.55555 -> 63.5555



64.55 -> 64.5
64.555 -> 64.56
64.5555 -> 64.555
64.55555 -> 64.5555



65.55 -> 65.5
65.555 -> 65.56
65.5555 -> 65.555
65.55555 -> 65.5555



66.55 -> 66.5
66.555 -> 66.56
66.5555 -> 66.555
66.55555 -> 66.5555

在JDK 1.7/1.8中有相同的结果

是不是JDK的bug?

最佳答案

不幸的是,这是生活的一部分,而且由于 double 类型在内部实现时基数为 2。对于科学编程来说,这是一件非常聪明的事情。但这确实意味着当您想查看或指定以 10 为基数的它们时,所见未必是所见。

例如,文字 10.555 实际上是一个略小于此的数字(10.5549999999999997157829056959599256515502929687...)所以明显的德国四舍五入实际上会将这个数字向下舍入 。你的问题中有很多类似的案例。

这本身并不是一个错误,但如果您需要精确舍入,那么您应该使用一个类来以任意精度表示十进制数。

使用 BigDecimal 是一种选择,但您严重滥用它!。通过使用 double 的构造函数(即 new BigDecimal(d)),d 中特有的不精确性只会被复制到 BigDecimal。因此,您应该改用 String 中的构造函数,或使用类似的方法。

最后看看http://www.exploringbinary.com/floating-point-converter .输入您的十进制数,然后查看它在转换为 float 时采用的值。

关于java - Java RoundingMode.HALF_EVEN 是错误吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38263415/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com