当前位置: 首页 > 知识库问答 >
问题:

Java8中的RoundingMode.half_down问题

康文昌
2023-03-14

我使用的是JDK1.8.045,我们的测试发现了路由中的一个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

共有1个答案

淳于熙云
2023-03-14

看来是有意的改变。JDK 1.7行为不正确。

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

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

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

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
 类似资料:
  • 问题内容: 我正在使用jdk 1.8.0_45,我们的测试发现了路由中的错误。当决定舍入的最后一个小数为5时,RoundingMode.HALF_DOWN与RoundingMode.HALF_UP相同。 我发现了RoundingMode.HALF_UP的相关问题,但已在更新40中修复。我也向oracle放了一个bug,但根据我的经验,它们确实没有响应。 实际结果:舍入10.5556舍入10.555

  • Android Studio有一个弹出窗口,告诉我在我运行SDK管理器并再次启动Android Studio之后,更新可用。我得到另一个弹出窗口,它让我访问Androids网站,它告诉我应该升级到Java JDK 8和JRE 8。在我尝试运行调试时,我出现了超过235个错误。我卸载了版本8,重新安装了7u80 JDK和JRE,现在我发现了34个错误。当我输入java-version时,我得到1.8

  • 因此,我希望这段代码能够在新的Java8date/time包下工作,因为它所做的只是将给定的ZonedDateTime转换成字符串,然后使用相同的内置DateTimeFormatter实例(ISO_INSTANT)返回: 但显然不是: 我已经看到了这个条目,但它对我没有帮助,因为a需要一个ZonedDateTime对象,而不是本地对象,还因为我已经安装了8U20:无法使用DateTimeForma

  • 我正在制作一个类似于LinkedListjava.util.类,得到了一个完全意想不到的类。我的IDE没有显示警告。仅供参考,我使用Java8u20。更新:固定在Java8u60。 3.T-T-h h-T-T-T-T-h-T-T-h-T-h-T-h-T-T-h h-T-T-h-T-T-T-h-T-h-T-T-T-T-T-T-T-T-h-T,i-i,i-T-i,i-T-T-T-i,i-s-a-s-s

  • 我使用LocalDateTime几乎导致了一个在线错误,直到例如: 我最初认为他应该2天回来,但结果是1天! 然后我看了看对应的源代码,我现在好像明白了:如果超过一天,不到两天,那就只返回一天。 我想问一下Java或Spring中是否有满足我需求的工具。 我想让它回到2天,这符合人们的直觉。 当然,我可以包装一个实用程序类来实现这一点,但我想知道Java中是否有可用的实现? 我的业务场景如下:如果

  • 本文向大家介绍Java8处理List的双层循环问题,包括了Java8处理List的双层循环问题的使用技巧和注意事项,需要的朋友参考一下 Java处理List的双层循环程序员经常遇到,一般都是当两个List某个值满足某条件时候,进行相应的处理; 1.list和map之间的相互转换 2.java8中的 groupingBy counting mapToDouble filter sum等函数方法的使用