java 使用BigDecimal進(jìn)行貨幣金額計(jì)算的操作
float和double只能用來(lái)做科學(xué)計(jì)算或者是工程計(jì)算,在商業(yè)計(jì)算中我們要用 java.math.BigDecimal。
而且使用BigDecimal類(lèi)也可以進(jìn)行大數(shù)的操作。
| 方法 | 類(lèi)型 | 描述 |
|---|---|---|
| public BigDecimal(double val) | 構(gòu)造 | 將double表示形式轉(zhuǎn)換為BigDecimal |
| public BigDecimal(int val) | 構(gòu)造 | 將int表示形式轉(zhuǎn)換為BigDecimal |
| public BigDecimal(String val) | 構(gòu)造 | 將字符串表示形式轉(zhuǎn)換為BigDecimal |
| public BigDecimal add(BigDecimal augend) | 普通 | 加法 |
| public BigDecimal subtract(BigDecimal subtrahend) | 普通 | 減法 |
| public BigDecimal multiply(BigDecimal multiplicand) | 普通 | 乘法 |
| public BigDecimal divide(BigDecimal divisor) | 普通 | 除法 |
一、 BigDecimal的計(jì)算
金額的計(jì)算BigDecimal類(lèi)
double d = 9.84; double d2 = 1.22; //注意需要使用BigDecimal(String val)構(gòu)造方法 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位小數(shù) BigDecimal bigDecimalDivide = bigDecimal.divide(bigDecimal2, scale, BigDecimal.ROUND_HALF_UP); double divide = bigDecimalDivide.doubleValue(); //格式化 double format = 12343171.6; //獲取常規(guī)數(shù)值格式 NumberFormat number = NumberFormat.getNumberInstance(); String str = number.format(format);//12,343,171.6 //獲取整數(shù)數(shù)值格式 NumberFormat integer = NumberFormat.getIntegerInstance(); str = integer.format(format);//如果帶小數(shù)會(huì)四舍五入到整數(shù)12,343,172 //獲取貨幣數(shù)值格式 NumberFormat currency = NumberFormat.getCurrencyInstance(); currency.setMinimumFractionDigits(2);//設(shè)置數(shù)的小數(shù)部分所允許的最小位數(shù)(如果不足后面補(bǔ)0) currency.setMaximumFractionDigits(4);//設(shè)置數(shù)的小數(shù)部分所允許的最大位數(shù)(如果超過(guò)會(huì)四舍五入) str = currency.format(format);//¥12,343,171.60 //獲取顯示百分比的格式 NumberFormat percent = NumberFormat.getPercentInstance(); percent.setMinimumFractionDigits(2);//設(shè)置數(shù)的小數(shù)部分所允許的最小位數(shù)(如果不足后面補(bǔ)0) percent.setMaximumFractionDigits(3);//設(shè)置數(shù)的小數(shù)部分所允許的最大位數(shù)(如果超過(guò)會(huì)四舍五入) str = percent.format(format);//1,234,317,160.00%
二、典型的Double類(lèi)型的數(shù)值運(yùn)算
/**
* double的計(jì)算不精確,會(huì)有類(lèi)似0.0000000000000002的誤差,正確的方法是使用BigDecimal或者用整型
* 整型地方法適合于貨幣精度已知的情況,比如12.11+1.10轉(zhuǎn)成1211+110計(jì)算,最后再/100即可
* 以下是摘抄的BigDecimal方法:
*/
public class DoubleUtil implements Serializable {
private static final long serialVersionUID = -3345205828566485102L;
// 默認(rèn)除法運(yùn)算精度
private static final Integer DEF_DIV_SCALE = 2;
/**
* 提供精確的加法運(yùn)算。
*
* @param value1 被加數(shù)
* @param value2 加數(shù)
* @return 兩個(gè)參數(shù)的和
*/
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();
}
/**
* 提供精確的減法運(yùn)算。
*
* @param value1 被減數(shù)
* @param value2 減數(shù)
* @return 兩個(gè)參數(shù)的差
*/
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();
}
/**
* 提供精確的乘法運(yùn)算。
*
* @param value1 被乘數(shù)
* @param value2 乘數(shù)
* @return 兩個(gè)參數(shù)的積
*/
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();
}
/**
* 提供(相對(duì))精確的除法運(yùn)算,當(dāng)發(fā)生除不盡的情況時(shí), 精確到小數(shù)點(diǎn)以后10位,以后的數(shù)字四舍五入。
*
* @param dividend 被除數(shù)
* @param divisor 除數(shù)
* @return 兩個(gè)參數(shù)的商
*/
public static Double divide(Double dividend, Double divisor) {
return divide(dividend, divisor, DEF_DIV_SCALE);
}
/**
* 提供(相對(duì))精確的除法運(yùn)算。 當(dāng)發(fā)生除不盡的情況時(shí),由scale參數(shù)指定精度,以后的數(shù)字四舍五入。
*
* @param dividend 被除數(shù)
* @param divisor 除數(shù)
* @param scale 表示表示需要精確到小數(shù)點(diǎn)以后幾位。
* @return 兩個(gè)參數(shù)的商
*/
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();
}
/**
* 提供指定數(shù)值的(精確)小數(shù)位四舍五入處理。
*
* @param value 需要四舍五入的數(shù)字
* @param scale 小數(shù)點(diǎn)后保留幾位
* @return 四舍五入后的結(jié)果
*/
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();
}
}
補(bǔ)充:Java存儲(chǔ)金額解決方案BigDecimal
使用BigDecimal來(lái)存儲(chǔ)金額數(shù)據(jù),數(shù)據(jù)庫(kù)中使用decimal類(lèi)型,長(zhǎng)度18,小數(shù)點(diǎn)2。
在JPA中創(chuàng)建時(shí)如下:
@Column(columnDefinition="decimal(18,2)") private BigDecimal price; //商品價(jià)格
在數(shù)據(jù)庫(kù)中創(chuàng)建時(shí)如下:

常用構(gòu)造器:
BigDecimal(double) 創(chuàng)建一個(gè)具有參數(shù)所指定雙精度值的對(duì)象
BigDecimal(long) 創(chuàng)建一個(gè)具有參數(shù)所指定長(zhǎng)整數(shù)值的對(duì)象
BigDecimal(String) 創(chuàng)建一個(gè)具有參數(shù)所指定以字符串表示的數(shù)值的對(duì)象
常用方法:加減乘除
add(BigDecimal) BigDecimal對(duì)象中的值相加,返回BigDecimal對(duì)象
subtract(BigDecimal) BigDecimal對(duì)象中的值相減,返回BigDecimal對(duì)象
multiply(BigDecimal) BigDecimal對(duì)象中的值相乘,返回BigDecimal對(duì)象
divide(BigDecimal) BigDecimal對(duì)象中的值相除,返回BigDecimal對(duì)象
常用方法:數(shù)據(jù)轉(zhuǎn)換
toString() 將BigDecimal對(duì)象中的值轉(zhuǎn)換成字符串
doubleValue() 將BigDecimal對(duì)象中的值轉(zhuǎn)換成雙精度數(shù)
floatValue() 將BigDecimal對(duì)象中的值轉(zhuǎn)換成單精度數(shù)
longValue() 將BigDecimal對(duì)象中的值轉(zhuǎn)換成長(zhǎng)整數(shù)
intValue() 將BigDecimal對(duì)象中的值轉(zhuǎn)換成整數(shù)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教。
相關(guān)文章
詳解springcloud之服務(wù)注冊(cè)與發(fā)現(xiàn)
本次分享的是關(guān)于springcloud服務(wù)注冊(cè)與發(fā)現(xiàn)的內(nèi)容,將通過(guò)分別搭建服務(wù)中心,服務(wù)注冊(cè),服務(wù)發(fā)現(xiàn)來(lái)說(shuō)明,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2018-06-06
JAVA刪除字符串固定下標(biāo)字串的實(shí)現(xiàn)
本文主要介紹了JAVA刪除字符串固定下標(biāo)字串的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-04-04
Java高級(jí)特性基礎(chǔ)之反射五連問(wèn)
反射賦予了我們?cè)谶\(yùn)行時(shí)分析類(lèi)以及執(zhí)行類(lèi)中方法的能力。通過(guò)反射你可以獲取任意一個(gè)類(lèi)的所有屬性和方法,你還可以調(diào)用這些方法和屬性。本文就來(lái)和大家詳細(xì)聊聊Java中的反射,感興趣的可以了解一下2023-01-01
idea配置Tomcat時(shí)沒(méi)有Artifacts選項(xiàng)的解決方法
本文主要介紹了idea配置Tomcat時(shí)沒(méi)有Artifacts選項(xiàng)的解決方法,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-05-05
談?wù)凧ava中整數(shù)類(lèi)型(short int long)的存儲(chǔ)方式
在java中的整數(shù)類(lèi)型有四種,分別是byte short in long,本文重點(diǎn)給大家介紹java中的整數(shù)類(lèi)型(short int long),由于byte只是一個(gè)字節(jié)0或1,在此就不多說(shuō)了,對(duì)java中的整數(shù)類(lèi)型感興趣的朋友一起學(xué)習(xí)吧2015-11-11
深入淺析drools中Fact的equality?modes
這篇文章主要介紹了drools中Fact的equality?modes的相關(guān)知識(shí),本文通過(guò)圖文實(shí)例代碼相結(jié)合給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-05-05
Java傳值調(diào)用和傳引用調(diào)用方式(參數(shù)引用為null問(wèn)題)
這篇文章主要介紹了Java傳值調(diào)用和傳引用調(diào)用方式(參數(shù)引用為null問(wèn)題),具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-09-09

