java 使用BigDecimal进行货币金额计算的操作

 更新时间:2021年02月19日 14:26:20   作者:柚子君.  
这篇文章主要介绍了java 使用BigDecimal进行货币金额计算的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧

float和double只能用来做科学计算或者是工程计算,在商业计算中我们要用 java.math.BigDecimal。

而且使用BigDecimal类也可以进行大数的操作。

方法 类型 描述
public BigDecimal(double val) 构造 将double表示形式转换为BigDecimal
public BigDecimal(int val) 构造 将int表示形式转换为BigDecimal
public BigDecimal(String val) 构造 将字符串表示形式转换为BigDecimal
public BigDecimal add(BigDecimal augend) 普通 加法
public BigDecimal subtract(BigDecimal subtrahend) 普通 减法
public BigDecimal multiply(BigDecimal multiplicand) 普通 乘法
public BigDecimal divide(BigDecimal divisor) 普通 除法

一、 BigDecimal的计算

金额的计算BigDecimal类

double d = 9.84;
double d2 = 1.22;
//注意需要使用BigDecimal(String val)构造方法
BigDecimal bigDecimal = new BigDecimal(Double.toString(d));
BigDecimal bigDecimal2 = new BigDecimal(Double.toString(d2));
//加法
BigDecimal bigDecimalAdd = bigDecimal.add(bigDecimal2);
double add = bigDecimalAdd.doubleValue();
//减法
BigDecimal bigDecimalSubtract = bigDecimal.subtract(bigDecimal2);
double subtract = bigDecimalSubtract.doubleValue();
//乘法
BigDecimal bigDecimalMultiply = bigDecimal.multiply(bigDecimal2);
double multiply = bigDecimalMultiply.doubleValue();
//除法
int scale = 2;//保留2位小数
BigDecimal bigDecimalDivide = bigDecimal.divide(bigDecimal2, scale, BigDecimal.ROUND_HALF_UP);
double divide = bigDecimalDivide.doubleValue();
//格式化
double format = 12343171.6;
//获取常规数值格式
NumberFormat number = NumberFormat.getNumberInstance();
String str = number.format(format);//12,343,171.6
//获取整数数值格式
NumberFormat integer = NumberFormat.getIntegerInstance();
str = integer.format(format);//如果带小数会四舍五入到整数12,343,172
//获取货币数值格式
NumberFormat currency = NumberFormat.getCurrencyInstance();
currency.setMinimumFractionDigits(2);//设置数的小数部分所允许的最小位数(如果不足后面补0)
currency.setMaximumFractionDigits(4);//设置数的小数部分所允许的最大位数(如果超过会四舍五入)
str = currency.format(format);//¥12,343,171.60
//获取显示百分比的格式
NumberFormat percent = NumberFormat.getPercentInstance();
percent.setMinimumFractionDigits(2);//设置数的小数部分所允许的最小位数(如果不足后面补0)
percent.setMaximumFractionDigits(3);//设置数的小数部分所允许的最大位数(如果超过会四舍五入)
str = percent.format(format);//1,234,317,160.00%

二、典型的Double类型的数值运算

/**
 * double的计算不精确,会有类似0.0000000000000002的误差,正确的方法是使用BigDecimal或者用整型
 * 整型地方法适合于货币精度已知的情况,比如12.11+1.10转成1211+110计算,最后再/100即可
 * 以下是摘抄的BigDecimal方法:
 */
public class DoubleUtil implements Serializable {
 private static final long serialVersionUID = -3345205828566485102L;
 // 默认除法运算精度
 private static final Integer DEF_DIV_SCALE = 2;
 /**
  * 提供精确的加法运算。
  *
  * @param value1 被加数
  * @param value2 加数
  * @return 两个参数的和
  */
 public static Double add(Double value1, Double value2) {
  BigDecimal b1 = new BigDecimal(Double.toString(value1));
  BigDecimal b2 = new BigDecimal(Double.toString(value2));
  return b1.add(b2).doubleValue();
 }
 /**
  * 提供精确的减法运算。
  *
  * @param value1 被减数
  * @param value2 减数
  * @return 两个参数的差
  */
 public static double sub(Double value1, Double value2) {
  BigDecimal b1 = new BigDecimal(Double.toString(value1));
  BigDecimal b2 = new BigDecimal(Double.toString(value2));
  return b1.subtract(b2).doubleValue();
 }
 /**
  * 提供精确的乘法运算。
  *
  * @param value1 被乘数
  * @param value2 乘数
  * @return 两个参数的积
  */
 public static Double mul(Double value1, Double value2) {
  BigDecimal b1 = new BigDecimal(Double.toString(value1));
  BigDecimal b2 = new BigDecimal(Double.toString(value2));
  return b1.multiply(b2).doubleValue();
 }
 /**
  * 提供(相对)精确的除法运算,当发生除不尽的情况时, 精确到小数点以后10位,以后的数字四舍五入。
  *
  * @param dividend 被除数
  * @param divisor 除数
  * @return 两个参数的商
  */
 public static Double divide(Double dividend, Double divisor) {
  return divide(dividend, divisor, DEF_DIV_SCALE);
 }
 /**
  * 提供(相对)精确的除法运算。 当发生除不尽的情况时,由scale参数指定精度,以后的数字四舍五入。
  *
  * @param dividend 被除数
  * @param divisor 除数
  * @param scale 表示表示需要精确到小数点以后几位。
  * @return 两个参数的商
  */
 public static Double divide(Double dividend, Double divisor, Integer scale) {
  if (scale < 0) {
   throw new IllegalArgumentException("The scale must be a positive integer or zero");
  }
  BigDecimal b1 = new BigDecimal(Double.toString(dividend));
  BigDecimal b2 = new BigDecimal(Double.toString(divisor));
  return b1.divide(b2, scale,RoundingMode.HALF_UP).doubleValue();
 }
 /**
  * 提供指定数值的(精确)小数位四舍五入处理。
  *
  * @param value 需要四舍五入的数字
  * @param scale 小数点后保留几位
  * @return 四舍五入后的结果
  */
 public static double round(double value,int scale){
  if(scale<0){
   throw new IllegalArgumentException("The scale must be a positive integer or zero");
  }
  BigDecimal b = new BigDecimal(Double.toString(value));
  BigDecimal one = new BigDecimal("1");
  return b.divide(one,scale, RoundingMode.HALF_UP).doubleValue();
 }
}

补充:Java存储金额解决方案BigDecimal

使用BigDecimal来存储金额数据,数据库中使用decimal类型,长度18,小数点2。

在JPA中创建时如下:

@Column(columnDefinition="decimal(18,2)") 
private BigDecimal price; //商品价格

在数据库中创建时如下:

常用构造器:

BigDecimal(double) 创建一个具有参数所指定双精度值的对象

BigDecimal(long) 创建一个具有参数所指定长整数值的对象

BigDecimal(String) 创建一个具有参数所指定以字符串表示的数值的对象

常用方法:加减乘除

add(BigDecimal) BigDecimal对象中的值相加,返回BigDecimal对象

subtract(BigDecimal) BigDecimal对象中的值相减,返回BigDecimal对象

multiply(BigDecimal) BigDecimal对象中的值相乘,返回BigDecimal对象

divide(BigDecimal) BigDecimal对象中的值相除,返回BigDecimal对象

常用方法:数据转换

toString() 将BigDecimal对象中的值转换成字符串

doubleValue() 将BigDecimal对象中的值转换成双精度数

floatValue() 将BigDecimal对象中的值转换成单精度数

longValue() 将BigDecimal对象中的值转换成长整数

intValue() 将BigDecimal对象中的值转换成整数

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。如有错误或未考虑完全的地方,望不吝赐教。

相关文章

  • 详解使用Spring Data repository进行数据层的访问问题

    详解使用Spring Data repository进行数据层的访问问题

    这篇文章主要介绍了使用Spring Data repository进行数据层的访问,抽象出Spring Data repository是因为在开发过程中,常常会为了实现不同持久化存储的数据访问层而写大量的大同小异的代码,本文给大家介绍的非常详细,需要的朋友参考下吧
    2022-06-06
  • java项目中的多线程实践记录

    java项目中的多线程实践记录

    项目开发中对于一些数据的处理需要用到多线程,比如文件的批量上传,数据库的分批写入,大文件的分段下载等,主要涉及到多线程的一些知识,本文通过实例代码给大家介绍的非常详细,需要的朋友参考下
    2021-11-11
  • 深入分析Spring BeanDefinition的构造元信息

    深入分析Spring BeanDefinition的构造元信息

    Bean Definition是一个包含Bean元数据的对象,它描述了如何创建Bean实例、Bean属性的值以及Bean之间的依赖关系,本文将带大家深入分析Spring BeanDefinition的构造元信息,需要的朋友可以参考下
    2024-01-01
  • 小议Java的源文件的声明规则以及编程风格

    小议Java的源文件的声明规则以及编程风格

    这篇文章主要介绍了小议Java的源文件的声明规则以及编程风格,仅给Java初学者作一个简单的示范,需要的朋友可以参考下
    2015-09-09
  • java7 新I/O知识点详解

    java7 新I/O知识点详解

    在本篇文章里小编给大家整理的是关于java7 新I/O知识点详解,有需要的朋友们可以学习下。
    2019-11-11
  • Java回调方法详解

    Java回调方法详解

    本篇文章主要介绍了Java回调方法的步骤、回调的例子、异步回调与同步回调、回调方法在通信中的应用等。具有一定的参考价值,下面跟着小编一起来看下吧
    2017-01-01
  • 加速spring/springboot应用启动速度详解

    加速spring/springboot应用启动速度详解

    这篇文章主要介绍了加速spring/springboot应用启动速度详解,本文通过实例代码给大家介绍的非常详细对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-07-07
  • java this的应用方法解析

    java this的应用方法解析

    这篇文章主要介绍了java this的应用方法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-10-10
  • Java中的Web MVC简介_动力节点Java学院整理

    Java中的Web MVC简介_动力节点Java学院整理

    MVC模型是一种架构型的模式,本身不引入新功能,只是帮助我们将开发的结构组织的更加合理,使展示与模型分离、流程控制逻辑、业务逻辑调用与展示逻辑分离
    2017-09-09
  • Java开发支付宝PC支付完整版

    Java开发支付宝PC支付完整版

    这篇文章主要介绍了Java开发支付宝PC支付完整版,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-08-08

最新评论