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
}
}

时间: 2024-11-06 18:04:33

JAVA中精确计算金额BigDecimal的相关文章

java精确计算之BigDecimal

Java中的计算主要有double,float,int,long,BigDecimal 1.float和double主要用户科学计算和工程计算,它们执行二进制浮点运算,这是为了在广泛的数值范围上提供较为精确的快速近似计算而设计的.然而它们并没有提供完全精确的结果,所以不应该被用于需要精确计算的场合. eg: double double_price1 = 1.03;  double double_price2 = 0.42;  System.out.println("double的计算值:&quo

第二章 Java浮点数精确计算

1.实际意义 在实际开发中,如果需要进行float或double的精确计算(尤其是财务计算),直接使用float或double是不行的(具体的例子看下边的代码的main方法的测试结果),需要使用BigDecimal. 2.代码 package com.xxx.util; import java.math.BigDecimal; /** * 浮点数精准算法 */ public class BigDecimalArithUtil { private static final int DIV_SCAL

Java中涉及到金额业务的处理

一.MySql数据库中如何定义关于金额字段: 建议定义成[DECIMAL]类型,而不是float或者是double,因为这个两者是以二进制储存的,存在一定的误差.具体事例可参考https://blog.csdn.net/xzp_12345/article/details/79460410. 此外还要注意的就是默认值, 一定写成0.00, 不要用默认的NULL, 否则在进行加减排序等操作时, 会带来转换的麻烦 二.Java实体类中定义成[BigDecimal]类型,涉及到金额的加减乘除及值大小比较

java中小数处理,bigDecimal类应用

1.构造一个BigDecimal对象: 1 //创建一个BigDecimal对象,初始化必须使用字符串,因为用数值初始化会得到近似值,不准确 2 BigDecimal bigDecimalOne = new BigDecimal("1.232324"); 3 4 //将浮点数装换成BigDecimal对象 5 double d = 1.3422424; 6 BigDecimal bigDecimalTwo =BigDecimal.valueOf(d); 2.BigDecimal成员方法

java的数字精确计算问题-BigDecimal

java的数字运算,偶尔喝出现精度的问题,以下阐述的 java的BigDecimal类的使用. 例如: System.out.println(0.9+0.3); 结果1.2 System.out.println(1.9+0.3); 结果2.1999999999999997 System.out.println(1.9+0.4); 结果2.3 java为了让float或者double类型能够精确的计算,提供了BigDecimal类. 示例如下: public static BigDecimal g

java中时间计算问题

由于业务中有一项需求需要在新员工三个月快转正的时候发邮件,所以写个小例子看看效果 时间在实体类中是long型,所以想的是先转出date,用calender计算加75天之后再转成String显示 pasting public static void main(String args[]) { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); long longTime = new Date().getTime(); Sy

JAVA简单精确计算工具类

1 public class ArithUtil { 2 3 // 默认除法运算精度 4 private static final int DEF_DIV_SCALE = 10; 5 6 private ArithUtil() { 7 8 } 9 10 /** 11 * 提供精确的加法运算. 12 * 13 * @param v1 14 * 被加数 15 * @param v2 16 * 加数 17 * @return 两个参数的和 18 */ 19 public static double a

Java中浮点型数据Float和Double进行精确计算的问题

一.浮点计算中发生精度丢失  大概很多有编程经验的朋友都对这个问题不陌生了:无论你使用的是什么编程语言,在使用浮点型数据进行精确计算时,你都有可能遇到计算结果出错的情况.来看下面的例子. // 这是一个利用浮点型数据进行精确计算时结果出错的例子,使用Java编写,有所省略. double a = (1.2 - 0.4) / 0.1;System.out.println(a); 如果你认为这个程序的输出结果是“8”的话,那你就错了.实际上,程序的输出结果是“7.999999999999999”.好

Java使用BigDecimal解决精确计算的问题

最近有人在微信上给我发了一个数学题目,如下图: 我看了之后感觉很是简单,但是却想了半天才解出来.解出来后我想到了用程序再解一遍,然而精确计算的问题却让人头疼不已. 解题思路: 思路其实很简单,暴力求解就可以,但是当你写了一个四重for循环后你会发现解不出来.由此考虑到结果可能是小数,便把增量改成了float类型,每次自增0.1. 当你写完满心欢喜地运行的时候会发现还是出不来结果.再改成double类型也同样是不行. 这是因为java中float类型相加是把十进制转化为二进制后相加然后把二进制结果