在JDK版本为1.8的情况运行下面的代码,会发现很神奇的情况(见运行结果)。

看如下代码:

package com.longge.mytest;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat; import org.junit.Test; public class TestDecimal {
@Test
public void test() {
BigDecimal a = new BigDecimal(0.075);
BigDecimal a1 = new BigDecimal(10.075);
BigDecimal a2 = new BigDecimal(100.075); BigDecimal b = new BigDecimal(0.074);
BigDecimal b1 = new BigDecimal(10.074);
BigDecimal b2 = new BigDecimal(100.074); BigDecimal c = new BigDecimal("0.075");
BigDecimal c1 = new BigDecimal("10.075");
BigDecimal c2 = new BigDecimal("100.075"); DecimalFormat df = new DecimalFormat("#0.00"); BigDecimal one = BigDecimal.ONE; // 0.07
System.out.println(a.divide(one, 2, RoundingMode.HALF_UP).doubleValue());
// 0.08
System.out.println(a.divide(one).add(new BigDecimal("0.0000000001")).setScale(2, RoundingMode.HALF_UP).doubleValue());
// 0.07
System.out.println(b.divide(one, 2, RoundingMode.HALF_UP).doubleValue());
// 0.07
System.out.println(b.divide(one).add(new BigDecimal("0.0000000001")).setScale(2, RoundingMode.HALF_UP).doubleValue());
// 0.07
System.out.println(df.format(0.074));
// 0.07
System.out.println(df.format(0.075));
// 0.08
System.out.println(c.divide(one, 2, RoundingMode.HALF_UP).doubleValue()); System.out.println("----------------------------"); // 10.07
System.out.println(a1.divide(one, 2, RoundingMode.HALF_UP).doubleValue());
// 10.08
System.out.println(a1.divide(one).add(new BigDecimal("0.0000000001")).setScale(2, RoundingMode.HALF_UP).doubleValue());
// 10.7
System.out.println(b1.divide(one, 2, RoundingMode.HALF_UP).doubleValue());
// 10.07
System.out.println(b1.divide(one).add(new BigDecimal("0.0000000001")).setScale(2, RoundingMode.HALF_UP).doubleValue());
// 10.07
System.out.println(df.format(10.074));
// 10.07
System.out.println(df.format(10.075));
// 10.08
System.out.println(c1.divide(one, 2, RoundingMode.HALF_UP).doubleValue()); System.out.println("----------------------------"); // 100.08
System.out.println(a2.divide(one, 2, RoundingMode.HALF_UP).doubleValue());
// 100.08
System.out.println(a2.divide(one).add(new BigDecimal("0.0000000001")).setScale(2, RoundingMode.HALF_UP).doubleValue());
// 100.07
System.out.println(b2.divide(one, 2, RoundingMode.HALF_UP).doubleValue());
// 100.07
System.out.println(b2.divide(one).add(new BigDecimal("0.0000000001")).setScale(2, RoundingMode.HALF_UP).doubleValue());
// 100.07
System.out.println(df.format(100.074));
// 100.08
System.out.println(df.format(100.075));
// 100.08
System.out.println(c2.divide(one, 2, RoundingMode.HALF_UP).doubleValue());
}
}

运行结果如下:

0.07
0.08
0.07
0.07
0.07
0.07
0.08
----------------------------
10.07
10.08
10.07
10.07
10.07
10.07
10.08
----------------------------
100.08
100.08
100.07
100.07
100.07
100.08
100.08

其中可选模式有:

1、 ROUND_UP:远离零方向舍入。向绝对值最大的方向舍入,只要舍弃位非0即进位。

2、 ROUND_DOWN:趋向零方向舍入。向绝对值最小的方向输入,所有的位都要舍弃,不存在进位情况。

3、 ROUND_CEILING:向正无穷方向舍入。向正最大方向靠拢。若是正数,舍入行为类似于ROUND_UP,若为负数,舍入行为类似于ROUND_DOWN。Math.round()方法就是使用的此模式。

4、 ROUND_FLOOR:向负无穷方向舍入。向负无穷方向靠拢。若是正数,舍入行为类似于ROUND_DOWN;若为负数,舍入行为类似于ROUND_UP。

5、 HALF_UP:最近数字舍入(5进)。这是我们最经典的四舍五入。

6、 HALF_DOWN:最近数字舍入(5舍)。在这里5是要舍弃的。

7、 HAIL_EVEN:银行家舍入法。

查看JDK的官方说明:

所以在做对精度要求高的计算时,要将double/float转成字符串后再转成BigDecimal进行计算

JAVA正确的四舍五入方法的更多相关文章

  1. 【转】java取整和java四舍五入方法

    java取整和java四舍五入方法 import java.math.BigDecimal; import java.text.DecimalFormat; public class TestGetI ...

  2. Java中的main()方法详解

    在Java中,main()方法是Java应用程序的入口方法,也就是说,程序在运行的时候,第一个执行的方法就是main()方法,这个方法和其他的方法有很大的不同,比如方法的名字必须是main,方法必须是 ...

  3. 如何在Java中避免equals方法的隐藏陷阱

    摘要 本文描述重载equals方法的技术,这种技术即使是具现类的子类增加了字段也能保证equal语义的正确性. 在<Effective Java>的第8项中,Josh Bloch描述了当继 ...

  4. 用javah 导出类的头文件, 常见的错误及正确的使用方法

    ******************************************************************************** 用javah 导出类的头文件, 常见的 ...

  5. 对java中的equals()方法的总结

    Java的基础学习总结--equals方法 一,等于方法介绍 1.1.通过下面的例子掌握等于的用法 1 package cn.galc.test; 2 3 public class TestEqual ...

  6. The superclass "javax.servlet.http.HttpServlet" was not found on the Java Build Path 解决方法

    项目忽然出现 The superclass "javax.servlet.http.HttpServlet" was not found on the Java Build Pat ...

  7. 两种计算Java对象大小的方法

    之前想研究一下unsafe类,碰巧在网上看到了这篇文章,觉得写得很好,就转载过来.原文出处是: http://blog.csdn.net/iter_zc/article/details/4182271 ...

  8. Eclipse、MinGW、JNI编写C++生成dll, Java端调用的完整示例(附java.lang.UnsatisfiedLinkError解决方法)

     Eclipse.MinGW.JNI编写C++生成dll, Java端调用的完整示例(附java.lang.UnsatisfiedLinkError解决方法) 问题背景:之前的JNI编程都是基于And ...

  9. 获取当前应用的系统路径工具类和java的System.getProperty()方法介绍

    java的System.getProperty()方法可以获取的值,如下: 对于Java程序,无论是未打包的还是打包的JAR或WAR文件,有时候都需要获取它运行所在目录信息,如何做到这一点呢? /** ...

随机推荐

  1. Asp.Net Core发布绑定域名和端口

    一.WebHostBuilder配置URL和端口进行侦听 UseUrls() 1.默认的ASP.NET Core项目绑定http://localhost:5000.通过使用UseUrls扩展方法——编 ...

  2. Dubbo服务化最佳实践

    分包 建议将服务接口,服务模型,服务异常等均放在 API 包中,因为服务模型及异常也是 API 的一部分,同时,这样做也符合分包原则:重用发布等价原则(REP),共同重用原则(CRP). 如果需要,也 ...

  3. matlib实现logistic回归算法(序一)

    数据下载:http://archive.ics.uci.edu/ml/datasets/Adult 数据描述:http://archive.ics.uci.edu/ml/machine-learnin ...

  4. linux下使用ack进行代码搜索

    1.安装 wget http://beyondgrep.com/ack-2.12-single-file sudo mv ack-2.12-single-file /usr/bin/ack sudo ...

  5. [leetcode]Regular Expression Matching @ Python

    原题地址:https://oj.leetcode.com/problems/regular-expression-matching/ 题意: Implement regular expression ...

  6. 二叉树 遍历 先序 中序 后序 深度 广度 MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  7. 汉字转拼音 pinyin4j 字符串 MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  8. 别再为了this发愁了:JS中的this机制

    题记:JavaScript中有很多令人困惑的地方,或者叫做机制.但是,就是这些东西让JavaScript显得那么美好而与众不同.比方说函数也是对象.闭包.原型链继承等等,而这其中就包括颇让人费解的th ...

  9. 【Java】Java-XML解析利器-SAX-高性能-易用

    Java-XML解析利器-SAX-高性能-易用 java xml 大_百度搜索 (3)java处理比较大的xml文件 - SegmentFault How to read UTF-8 XML file ...

  10. 【Spark】SparkStreaming-输出到Kafka

    SparkStreaming-输出到Kafka sparkstreaming output kafka_百度搜索 SparkStreaming采用直连方式(Direct Approach)获取Kafk ...