BigDecimal 类的使用

1、使用 BigDecimal 的原因

  由于需要计算金额,所有需要高精度计算,所有需要使用 BigDecimal 类。

BigDecimal能够精确的表示一个小数,常用于商业和科学计算;float,double不能精确的表示一个小数。

2、常用方法

2.1 加法(add)

  分别用两种不同的数据类型(long 和 string)创建 BigDecimal 对象;

import java.math.BigDecimal;

public class BigDecimalTest {
/**
* 使用BigDecimal,参数类型是double类型,计算还是不精确
*/
@Test
public void testAdd1(){
BigDecimal b1 = new BigDecimal(0.05);
BigDecimal b2 = new BigDecimal(0.01);
System.out.println(b1.add(b2));
//输出:0.06000000000000000298372437868010820238851010799407958984375
} /**
* 使用BigDecimal,参数类型是String类型,计算结果精确
*/
@Test
public void testAdd2(){
BigDecimal b1 = new BigDecimal("0.05");
BigDecimal b2 = new BigDecimal("0.01");
System.out.println(b1.add(b2));
//输出:0.06
}
}

  从上面的结果可以看出使用 string 类型的才能得到精确的计算结果。所有在计算金额时注意使用 string 类型创建对象。

2.2 减法(subtract)

import java.math.BigDecimal;

public class BigDecimalTest {
/**
* 测试减法 参数类型是double类型,计算还是不精确
*/
@Test
public void testSubtract1(){
BigDecimal b1 = new BigDecimal(0.05);
BigDecimal b2 = new BigDecimal(0.01);
System.out.println(b1.subtract(b2));
//输出:0.04000000000000000256739074444567449972964823246002197265625
} /**
* 测试减法,参数类型是String类型,计算结果精确
*/
@Test
public void testSubtract2(){
BigDecimal b1 = new BigDecimal("0.05");
BigDecimal b2 = new BigDecimal("0.01");
System.out.println(b1.subtract(b2));
//输出:0.04
}
}

2.3 乘法(multiply)

import java.math.BigDecimal;

public class BigDecimalTest {
/**
* 测试乘法 参数类型是double类型,计算还是不精确
*/
@Test
public void testMultiply1(){
BigDecimal b1 = new BigDecimal(0.05);
BigDecimal b2 = new BigDecimal(0.01);
System.out.println(b1.multiply(b2));
//输出:0.0005000000000000000381639164714897566548413219067927041589808827754781955614304944646164585719816386699676513671875
} /**
* 测试乘法,参数类型是String类型,计算结果精确
*/
@Test
public void testMultiply2(){
BigDecimal b1 = new BigDecimal("0.05");
BigDecimal b2 = new BigDecimal("0.01");
System.out.println(b1.multiply(b2));
//输出:0.0005
}
}

2.4 除法(divide)

2.4.1 除不尽,报错

  由于10/3除不尽,商是无限小数,所以报错;

  Non-terminating decimal expansion; no exact representable decimal result.

import java.math.BigDecimal;

public class BigDecimalTest {
/**
* 测试除法 参数类型是double类型
*/
@Test
public void testDivide1(){
BigDecimal b1 = new BigDecimal(0.1);
BigDecimal b2 = new BigDecimal(0.03);
System.out.println(b1.divide(b2));
//报错 java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.
} /**
* 测试除法,参数类型是String类型
*/
@Test
public void testDivide2(){
BigDecimal b1 = new BigDecimal("0.1");
BigDecimal b2 = new BigDecimal("0.03");
System.out.println(b1.divide(b2));
//报错 java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.
}
}
2.4.2 解决办法

  其实devide的函数定义如下:

BigDecimal.divide(BigDecimal divisor, int scale, RoundingMode roundingMode);

  • scale为小数位数;
  • roundingMode为小数模式;

小数模型有以下类型:

  • ROUND_CEILING

    如果 BigDecimal 是正的,则做 ROUND_UP 操作;如果为负,则做 ROUND_DOWN 操作。
  • ROUND_DOWN

    从不在舍弃(即截断)的小数之前增加数字。
  • ROUND_FLOOR

    如果 BigDecimal 为正,则作 ROUND_UP ;如果为负,则作 ROUND_DOWN 。
  • ROUND_HALF_DOWN

    若舍弃部分> .5,则作 ROUND_UP;否则,作 ROUND_DOWN 。
  • ROUND_HALF_EVEN

    如果舍弃部分左边的数字为奇数,则作 ROUND_HALF_UP ;如果它为偶数,则作 ROUND_HALF_DOWN 。
  • ROUND_HALF_UP

    若舍弃部分>=.5,则作 ROUND_UP ;否则,作 ROUND_DOWN 。
  • ROUND_UNNECESSARY

    该“伪舍入模式”实际是指明所要求的操作必须是精确的,,因此不需要舍入操作。
  • ROUND_UP

    总是在非 0 舍弃小数(即截断)之前增加数字。

  所有除法应该写成以下形式;

BigDecimal num3 = num1.divide(num2,10,ROUND_HALF_DOWN);

import java.math.BigDecimal;

public class BigDecimalTest {
/**
* 测试除法 参数类型是double类型
*/
@Test
public void testDivide3(){
BigDecimal b1 = new BigDecimal(0.1);
BigDecimal b2 = new BigDecimal(0.03);
System.out.println(b1.divide(b2, 10, ROUND_HALF_DOWN));
//输出:3.3333333333
} /**
* 测试除法,参数类型是String类型
*/
@Test
public void testDivide4(){
BigDecimal b1 = new BigDecimal("0.1");
BigDecimal b2 = new BigDecimal("0.03");
System.out.println(b1.divide(b2, 10, ROUND_HALF_DOWN));
//输出:3.3333333333
}

3、小结

  1. 使用 string 类型创建 BigDecimal 对象来进行精确计算;
  2. 进行除法计算时,需要添加参数(scale)小数位数和(roundingMode)小数模式;避免出现除不尽报错的现象;

BigDecimal 类的使用的更多相关文章

  1. BigDecimal类

    如果需要精确的计算结果,则必须使用BigDecimal类,而且使用BigDecimal类也可以进行大数的操作. //========================================== ...

  2. Java大数处理类:BigInteger类和BigDecimal类

    当我们要处理非常大的数据时,平常用的数据类型已不足以表示,在Java中有两个类BigInteger和BigDecimal分别表示大整数类和大浮点数类,这两个类在理论上只要计算机内存足够大就能够表示无线 ...

  3. BIgInteger类和BigDecimal类的理解

    第一部分: 这两个类位于java.math包内,要使用它们必须在类前面引用该包:import java.math.BigInteger;和import java.math.BigDecimal; Bi ...

  4. Java API —— BigDecimal类

    1.BigDecimal类概述  由于在运算的时候,float类型和double很容易丢失精度,演示案例.所以,为了能精确的表示.计算浮点数,Java提供了BigDecimal 不可变的.任意精度的有 ...

  5. 用BigDecimal类实现Fibonacci算法

    Fibonacci(N)=Fibonacii(N-1)+Fibonacci(N-2) 其中 Fibonacci(0)=0;Fibonacci(1)=1 用循环或则递归实现Fibonacci算法很简单, ...

  6. java.math.BigDecimal类

    BigDecimal类用于高精度计算.一般的float型和Double型数据只可以用来做科学计算或者是工程计算,由于在商业计算中,要求的数字精度比较高,所以要用到java.math.BigDecima ...

  7. Java基础知识强化88:BigDecimal类之BigDecimal类引入和概述 以及 BigDecimal的使用(加减乘除)

    1. BigDecimal类概述: 由于在运算的时候,float类型和double很容易丢失精度.所以为了能够精确的表达.计算浮点数,Java提供了BigDecimal. BigDecimal:不可变 ...

  8. BigDecimal类对象的使用详解

    双精度浮点型变量double可以处理16位有效数.在实际应用中,需要对更大或者更小的数进行运算和处理.Java在java.math包中提供的API类BigDecimal,用来对超过16位有效位的数进行 ...

  9. BigDecimal类的简单使用方法

    一提到Java里面的商业计算,我们都知道不能用float和double,由于他们无法进行精确计算.可是Java的设计者给编程人员提供了一个非常实用的类BigDecimal,他能够完好float和dou ...

  10. 金额的计算BigDecimal类

    金额的计算BigDecimal类 double d = 9.84; double d2 = 1.22; //注意需要使用BigDecimal(String val)构造方法 BigDecimal bi ...

随机推荐

  1. 使用git提交代码流程

    一.拉取最新代码 一般在本地进行开发时,都是切换到自己的dev分支进行开发,当开发完成需要进行代码提交,在进行代码提交前需要先进行拉取远程仓库代码,进行更新,但是此时会提示需要将本地代码进行commi ...

  2. Python 用队列实现多线程并发

    # Python queue队列,实现并发,在网站多线程推荐最后也一个例子,比这货简单,但是不够规范 # encoding: utf-8 __author__ = 'yeayee.com' # 由本站 ...

  3. D02——C语言基础学PYTHON

    C语言基础学习PYTHON——基础学习D02 20180801内容纲要: 1 字符串的系列操作 2 集合 3  文件的读写 4 字符编码转换 5 小结 6 练习:三级菜单(有彩蛋) 1 字符串的系列操 ...

  4. Keil软件编程问题归总

    Q:KEIL.uVision.RealView.MDK.KEIL C51之间的关系纠葛(比较区别)? A: KEIL是公司的名称,有时候也指KEIL公司的所有软件开发工具,目前2005年Keil由AR ...

  5. Tensorflow入门----占位符、常量和Session

    安装好TensorFlow之后,开一个python环境,就可以开始运行和使用TensorFlow了. 先给一个实例, #先导入TensorFlow import tensorflow as tf he ...

  6. 使用hexo+coding搭建免费个人博客

    1.检测node和npm 先检测一下有没有node.js和npm $ node -v //如果有,说明node.js安装成功! $ node -v v8.4.0 //如果有,说明npm安装成功! $n ...

  7. Echarts【1、数据过多导致显示不全分页,2、数据展示探讨分析】

    var len=<c:out value="${len }"></c:out>; var dataZoom_end=null; //为空默认100%所以默认 ...

  8. 常用DOS命令和Linux命令

    DOS命令 1.查询端口占用情况:netstat -aon |findstr "8080"; 查看端口进程号: 2.查看进程号信息:   tasklist |findstr &qu ...

  9. docker 磁盘清理 相关

    用户在使用 Docker 部署业务一段时间后,可能会发现宿主节点的磁盘容量持续增长,甚至将磁盘空间耗尽进而引发宿主机异常,进而对业务造成影响. 本文先对 Docker 的空间分析与清理进行说明,然后对 ...

  10. mfix输出自定义数据

    有时候需要输出一些自定义的网格或者DEM颗粒信息,比如输出颗粒的受力,这里举例颗粒自定义数据的输出.网格自定义输出方法类似. 首先用FileLocatorPro(网上很多绿色版),搜索一下代码里mod ...