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对象中的值转换成整数

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

相关文章

  • Java中的Calendar日历API用法完全解析

    Java中的Calendar日历API用法完全解析

    今天特别整理了针对Java中的Calendar日历API用法完全解析,通过Calendar API我们可以对Calendar所提供的时间日期字段进行各种自定义操作,首先还是从Calendar的基础入手:
    2016-06-06
  • Java17和springboot3.0使用shiro报ClassNotFoundException的解决

    Java17和springboot3.0使用shiro报ClassNotFoundException的解决

    本文主要介绍了Java17和springboot3.0使用shiro报ClassNotFoundException的解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-04-04
  • SpringBoot 快速实现分库分表的2种方式

    SpringBoot 快速实现分库分表的2种方式

    本文将为您介绍 ShardingSphere 的一些基础特性和架构组成,以及在 Springboot 环境下通过JAVA编码和Yml配置两种方式快速实现分库分表功能,感兴趣的朋友跟随小编一起看看吧
    2023-06-06
  • Java将Object转换为数组的代码

    Java将Object转换为数组的代码

    这篇文章主要介绍了Java将Object转换为数组的情况,今天在使用一个别人写的工具类,这个工具类,主要是判空操作,包括集合、数组、Map等对象是否为空的操作,需要的朋友可以参考下
    2022-09-09
  • Java AtomicInteger类的使用方法详解

    Java AtomicInteger类的使用方法详解

    这篇文章主要介绍了Java AtomicInteger类的使用方法详解,文中有具体实例代码,具有一定参考价值,需要的朋友可以了解下。
    2017-10-10
  • 深入理解Java中的HashMap

    深入理解Java中的HashMap

    HashMap是Java程序员使用频率最高的用于映射(键值对)处理的数据类型。随着JDK(Java Developmet Kit)版本的更新,JDK1.8对HashMap底层的实现进行了优化,例如引入红黑树的数据结构和扩容的优化等。本文将深入探讨HashMap的结构实现和功能原理
    2021-06-06
  • Java8 Stream API 详细使用方法与操作技巧指南

    Java8 Stream API 详细使用方法与操作技巧指南

    这篇文章主要介绍了Java8 Stream API 详细使用方法与操作技巧,总结分析了Java8 Stream API 基本功能、使用方法与操作注意事项,需要的朋友可以参考下
    2020-05-05
  • 一文带你初识java中的String类

    一文带你初识java中的String类

    String代表字符串,Java 程序中的所有字符串字面值(如 "abc" )都作为此类的实例实现,这篇文章主要给大家介绍了关于java中String类的相关资料,需要的朋友可以参考下
    2021-10-10
  • 解决IDEA创建第一个spring boot项目提示cannot resolve xxx等错误

    解决IDEA创建第一个spring boot项目提示cannot resolve xxx等

    这篇文章主要介绍了解决IDEA创建第一个spring boot项目提示cannot resolve xxx等错误问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-01-01
  • Springboot如何连接远程服务器上的数据库实践

    Springboot如何连接远程服务器上的数据库实践

    本文主要介绍了Springboot如何连接远程服务器上的数据库实践,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-04-04

最新评论