当前位置: 首页 > news >正文

JAVA中精确计算金额BigDecimal

package com.chauvet.utils;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.NumberFormat;

/***
* 
* 金额
* 
* 如果需要精确计算,必须用String来够造BigDecimal! !!
* 
* Java里面的商业计算,不能用float和double,因为他们无法 进行精确计算。
* 但是Java的设计者给编程人员提供了一个很有用的类BigDecimal,
* 他可以完善float和double类无法进行精确计算的缺憾。
* BigDecimal类位于java.maths类包下。
* 它的构造函数很多,最常用的:
* BigDecimal(double val)
* BigDecimal(String str)
* BigDecimal(BigInteger val)
* BigDecimal(BigInteger unscaledVal, int scale)

*
* @author wxw
*
*/
public class AmountUtil {

/***
* 保留2位小数
* 四舍五入
* @param a
* 
* @return
* 返回一个double类型的2位小数
*/
public static Double get2Double(Double doubleVal,int scale){
if(null == doubleVal){
doubleVal = new Double(0);
}
return new BigDecimal(doubleVal).setScale(scale, BigDecimal.ROUND_HALF_UP).doubleValue();
}

/***
* 格式化Double类型并保留scale位小数
* 四舍五入
* @param doubleVal
* @param scale
* scale必须为大于0的正整数,不能等于0
* @return
*/
public static String formatBy2Scale(Double doubleVal,int scale){
if(null == doubleVal){
doubleVal = new Double(0);
}
StringBuffer sbStr = new StringBuffer("0.");
for (int i = 0; i < scale; i++) {
sbStr.append("0");
}
DecimalFormat myformat = new DecimalFormat(sbStr.toString());
return myformat.format(doubleVal);
}

/***
* Double类型相加 <font color="red">+</font><br/>
* ROUND_HALF_UP <font color="red">四舍五入</font><br/>
* @param val1
* 
* @param val2
* 
* @param scale
* <font color="red">保留scale位小数</font><br/>
* @return
*/
public static Double add(Double val1,Double val2,int scale){
if(null == val1){
val1 = new Double(0);
}
if(null == val2){
val2 = new Double(0);
}
return new BigDecimal(Double.toString(val1)).add(new BigDecimal(Double.toString(val2))).setScale(scale, BigDecimal.ROUND_HALF_UP).doubleValue();
}

/***
* Double类型相减 <font color="red">—</font><br/>
* ROUND_HALF_UP <font color="red">四舍五入</font><br/>
* @param val1
* 
* @param val2
* 
* @param scale
* <font color="red">保留scale位小数</font><br/>
* @return
*/
public static Double subtract(Double val1,Double val2,int scale){
if(null == val1){
val1 = new Double(0);
}
if(null == val2){
val2 = new Double(0);
}
return new BigDecimal(Double.toString(val1)).subtract(new BigDecimal(Double.toString(val2))).setScale(scale, BigDecimal.ROUND_HALF_UP).doubleValue();
}

/***
* Double类型相乘 <font color="red">*</font><br/>
* ROUND_HALF_UP <font color="red">四舍五入</font><br/>
* @param val1
* 
* @param val2
* 
* @param scale
* <font color="red">保留scale位小数</font><br/>
* @return
*/
public static Double multiply(Double val1,Double val2,int scale){
if(null == val1){
val1 = new Double(0);
}
if(null == val2){
val2 = new Double(0);
}
return new BigDecimal(Double.toString(val1)).multiply(new BigDecimal(Double.toString(val2))).setScale(scale, BigDecimal.ROUND_HALF_UP).doubleValue();
}

/***
* Double类型相除 <font color="red">/</font><br/>
* ROUND_HALF_UP <font color="red">四舍五入</font><br/>
* @param val1
* 
* @param val2
* 
* @param scale
* <font color="red">保留scale位小数</font><br/>
* @return
*/
public static Double divide(Double val1,Double val2,int scale){
if(null == val1){
val1 = new Double(0);
}
if(null == val2 || val2 == 0){
val2 = new Double(1);
}
return new BigDecimal(Double.toString(val1)).divide(new BigDecimal(Double.toString(val2))).setScale(scale, BigDecimal.ROUND_HALF_UP).doubleValue();
}


/***
* Double类型取余    <font color="red">%</font><br/>
* ROUND_HALF_UP <font color="red">四舍五入</font><br/>
* @param val1
* 
* @param val2
* 
* @param scale
* <font color="red">保留scale位小数</font><br/>
* @return
*/
public static int divideAndRemainder(Double val1,Double val2,int scale){
if(null == val1){
val1 = new Double(0);
}
if(null == val2 || val2 == 0){
val2 = new Double(1);
}
return new BigDecimal(Double.toString(val1)).divideAndRemainder(new BigDecimal(Double.toString(val2)))[1].setScale(scale, BigDecimal.ROUND_HALF_UP).intValue();
}

/***
* 格式化Double类型数据
* 
* @param val
* @param fmt
* NumberFormat currency = NumberFormat.getCurrencyInstance(); //建立货币格式化引用 
* NumberFormat percent = NumberFormat.getPercentInstance(); //建立百分比格式化引用 
* @param maximumFractionDigits
* 如果是百分比 设置小数位数(四舍五入)
* @return
*/
public static String formatByNumberFormat(Double val,NumberFormat fmt,int maximumFractionDigits){
if(fmt.equals(NumberFormat.getPercentInstance())){
fmt.setMaximumFractionDigits(maximumFractionDigits); //百分比小数点最多3位 
}
return fmt.format(val);

}

/***
* 比较大小
* -1、0、1,即左边比右边数大,返回1,相等返回0,比右边小返回-1。
* @param doubleVal
* @return
*/
public static int compareTo(Double val1,Double val2){
if(null == val1){
val1 = new Double(0);
}
if(null == val2){
val2 = new Double(0);
}
return new BigDecimal(val1).compareTo(new BigDecimal(val2));
}


public static void main(String[] args) {

//    System.out.println(AmountUtil.get2Double(null,3));
//    System.out.println(AmountUtil.add(12.2155, null,4));
//    System.out.println(AmountUtil.subtract(12.2155, 1D,2));
//    System.out.println(AmountUtil.multiply(12.2155, 2D,2));
//    System.out.println(AmountUtil.divide(44.13, 2D,2));
//    System.out.println(AmountUtil.divideAndRemainder(43D, 8D,0));
//    System.out.println(AmountUtil.formatByNumberFormat(0.123456, NumberFormat.getPercentInstance(),3));
//    System.out.println(AmountUtil.formatBy2Scale(12.23457,3));


DecimalFormat df = new DecimalFormat("0.00\u2030"); //"\u2030"表示乘以1000并显示为千分数
System.out.println(df.format(12.1233)); //8-->1234567.89‰ 

df = new DecimalFormat("0,000.0#");//在数字中添加逗号
System.out.println(df.format(123456789.12345)); //5-->-1,234.57 


df = new DecimalFormat("0");//不保留小数点 四舍五入
System.out.println(df.format(123456789.9876)); //5-->-1,234.57 
}
}
  

 

转载于:https://www.cnblogs.com/chauvet/p/5832768.html

相关文章:

  • java并发编程实践笔记
  • 第四章 進程調度
  • volatile原理与技巧
  • java I/O的基本使用
  • java多线程中的join方法详解
  • java多线程总结
  • PHP 图片处理工具类(添加水印与生成缩略图)
  • MyEclipse 8.0 GA 搭建 Struts2 + Spring2 + Hibernate3 (测试)
  • MyEclipse从数据库反向生成实体类之Hibernate方式
  • 城市选择案例
  • 《深入浅出 Java Concurrency》——原子操作
  • 第18章 认识系统服务(daemons)
  • 《深入浅出 Java Concurrency》—锁机制(一)Lock与ReentrantLock
  • iOS开发中那些高效常用的宏
  • 《深入浅出 Java Concurrency》—锁机制(二) AQS
  • 【Amaple教程】5. 插件
  • 2017年终总结、随想
  • CAP 一致性协议及应用解析
  • Github访问慢解决办法
  • iOS 颜色设置看我就够了
  • Laravel 菜鸟晋级之路
  • Rancher如何对接Ceph-RBD块存储
  • yii2权限控制rbac之rule详细讲解
  • 读懂package.json -- 依赖管理
  • 前言-如何学习区块链
  • 使用iElevator.js模拟segmentfault的文章标题导航
  • Spring Batch JSON 支持
  • 阿里云重庆大学大数据训练营落地分享
  • (1)安装hadoop之虚拟机准备(配置IP与主机名)
  • (145)光线追踪距离场柔和阴影
  • (4)(4.6) Triducer
  • (二)斐波那契Fabonacci函数
  • (附源码)springboot 校园学生兼职系统 毕业设计 742122
  • (十二)devops持续集成开发——jenkins的全局工具配置之sonar qube环境安装及配置
  • (转) 深度模型优化性能 调参
  • .dwp和.webpart的区别
  • .locked1、locked勒索病毒解密方法|勒索病毒解决|勒索病毒恢复|数据库修复
  • .NET 3.0 Framework已经被添加到WindowUpdate
  • .Net Core与存储过程(一)
  • .Net6使用WebSocket与前端进行通信
  • .Net6支持的操作系统版本(.net8已来,你还在用.netframework4.5吗)
  • .Net程序猿乐Android发展---(10)框架布局FrameLayout
  • .net下简单快捷的数值高低位切换
  • .project文件
  • ?
  • @converter 只能用mysql吗_python-MySQLConverter对象没有mysql-connector属性’...
  • @FeignClient注解,fallback和fallbackFactory
  • @private @protected @public
  • [ 英语 ] 马斯克抱水槽“入主”推特总部中那句 Let that sink in 到底是什么梗?
  • [ActionScript][AS3]小小笔记
  • [C++] new和delete
  • [daily][archlinux][game] 几个linux下还不错的游戏
  • [Excel]如何找到非固定空白格數列的條件數據? 以月份報價表單為例
  • [LeetCode] Binary Tree Preorder Traversal 二叉树的先序遍历
  • [leetcode]56. Merge Intervals归并区间