Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/345.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java8中的RoundingMode.HALF_DOWN问题_Java_Migration_Java 8_Rounding - Fatal编程技术网

Java8中的RoundingMode.HALF_DOWN问题

Java8中的RoundingMode.HALF_DOWN问题,java,migration,java-8,rounding,Java,Migration,Java 8,Rounding,我正在使用JDK1.8.045,我们的测试发现了rouding中的一个bug。 当决定舍入的最后一个小数点为5时,RoundingMode.HALF_DOWN与RoundingMode.HALF_UP的工作原理相同 我发现了RoundingMode.HALF_UP的相关问题,但它们在更新40中已修复。我也给甲骨文设置了一个bug,但根据我的经验,他们真的没有反应 package testjava8; import java.math.RoundingMode; import java.text

我正在使用JDK1.8.045,我们的测试发现了rouding中的一个bug。 当决定舍入的最后一个小数点为5时,RoundingMode.HALF_DOWN与RoundingMode.HALF_UP的工作原理相同

我发现了RoundingMode.HALF_UP的相关问题,但它们在更新40中已修复。我也给甲骨文设置了一个bug,但根据我的经验,他们真的没有反应

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

预期结果(使用jdk 1.7获得): 四舍五入 10.5555 使聚集
10.5556

看来这是有意的改变。JDK1.7行为不正确

问题在于,您无法使用
double
类型表示数字
10.55555
。它以IEEE二进制格式存储数据,因此当您将十进制数
10.55555
分配给
double
变量时,您实际上得到了可以用IEEE格式表示的最接近的值:
10.55550000000000 210320649784989655017852783203125
。此数字大于
10.55555
,因此在
HALF_DOWN
模式下正确舍入为
10.5556

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

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


行为的变化记录在

使用
NumberFormat
DecimalFormat
类时,JDK以前版本的舍入行为在某些情况下是错误的。[……]

例如,使用默认推荐的
NumberFormatFormat
API表单时:
NumberFormat nf=java.text.NumberFormat.getInstance()
后跟
nf.format(0.8055d)
,值0.8055d在计算机中记录为0.80549999999999378275106209912337362766265869140625,因为该值不能以二进制格式精确表示。这里,默认的舍入规则是“半偶数”,在JDK 7中调用format()的结果是错误的输出“0.806”,而正确的结果是“0.805”,因为计算机在内存中记录的值是“低于”平局

对于程序员选择的任何模式(非默认模式)可能定义的所有舍入位置,也会实现此新行为


这个bug不会在JDK1.8.0_45中重现。我读了你说的问题,但不是同一个问题。这个问题已经解决了。请注意,Java允许在数字文本中使用下划线。使用它们来标记舍入点可能有助于读者通过这堆
5
s…我正要发布一个类似的答案,因为我觉得这种行为似乎是正确的。这将是一个问题。然而,似乎应该如此,为什么7u80会出现这种情况?或者这可能是一个不同的bug?DecimalFormat类没有说明它是否能够处理double的精确表示或规范表示(除非我错过了它),所以这两种行为似乎都是可以接受的。。。
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