在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. RF的特征子集选取策略(spark ml)

    支持连续变量和类别变量,类别变量就是某个属性有三个值,a,b,c,需要用Feature Transformers中的vectorindexer处理 上来是一堆参数 setMaxDepth:最大树深度 ...

  2. Grizzly HTTP CoDec ThreadCache 浅析

    Grizzly 的 HTTP CoDec 实现方法更 Netty 的 CoDec 完全不同, 他们思想上的差异主要在于: 1. 解码方式 Grizzly 使用流式解码, 它的HttpHeader对象内 ...

  3. 支付宝 iphone6 指纹验证失败

    重启 iphone6  就可以了. 再次打开 支付宝 那个 指纹功能,就有一个弹出框 可以按指纹了.

  4. ASP.NET Razor 简介

    ylbtech-.NET: ASP.NET Razor 简介 Razor 不是一种编程语言.它是服务器端的标记语言. 1. 什么是 Razor?返回顶部 Razor 是一种标记语法,可以让您将基于服务 ...

  5. 一个可用来记录Isilon各个节点的CPU,网络,磁盘性能的命令

    通过查看命令isi statistics system的帮助信息,拼出了下面的命令. isi statistics system list --nodes=all --degraded --forma ...

  6. js将滚动条滚动到指定位置的方法

    代码如下(主要是通过设置Location的hash属性): <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN& ...

  7. jQuery操作radio、checkbox、select 集合

    1.radio:单选框 HTML代码: <input type="radio" name="radio" id="radio1" va ...

  8. vue里ref ($refs)用法

    ref 有三种用法: 1.ref 加在普通的元素上,用this.ref.name 获取到的是dom元素 2.ref 加在子组件上,用this.ref.name 获取到的是组件实例,可以使用组件的所有方 ...

  9. Win32进程创建、进程快照、进程终止用例

    进程创建: 1 #include <windows.h> #include <stdio.h> int main() { // 创建打开系统自带记事本进程 STARTUPINF ...

  10. MFC路径层的使用(BeginPath和EndPath函数)

    响应WM_PAINT消息的代码如下: void CTextView::OnDraw(CDC* pDC) { CTextDoc* pDoc = GetDocument(); ASSERT_VALID(p ...