BigDecimal 詳解
參考: https://blog.csdn.net/wangjunjun2008/article/details/45559655
- Java中提供了大數字(超過16位有效位)的操作類,即 java.math.BinInteger 類和 java.math.BigDecimal 類,用於高精度計算.
- 其中 BigInteger 類是針對大整數的處理類,而 BigDecimal 類則是針對大小數的處理類.
BigDecimal 類的實現用到了 BigInteger類,不同的是 BigDecimal 加入了小數的概念. - float和Double只能用來做科學計算或者是工程計算;在商業計算中,對數字精度要求較高,必須使用 BigInteger 類和 BigDecimal 類,它支持任何精度的定點數,可以用它來精確計算貨幣值.
- BigDecimal類創建的是對象,不能使用傳統的+、-、*、/等算術運算符直接對其進行數學運算,而必須調用其對應的方法.方法的參數也必須是BigDecimal類型的對象.
1.爲何BigDecimal不會丟失精度,Double會丟失。
-
借用《Effactive Java》這本書中的話,float和double類型的主要設計目標是爲了科學計算和工程計算。他們執行二進制浮點運算,這是爲了在廣域數值範圍上提供較爲精確的快速近似計算而精心設計的。然而,它們沒有提供完全精確的結果,所以不應該被用於要求精確結果的場合。但是,商業計算往往要求結果精確,這時候BigDecimal就派上大用場啦。
-
BigDecimal簡介
-
BigDecimal 由任意精度的整數非標度值 和32 位的整數標度 (scale) 組成。如果爲零或正數,則標度是小數點後的位數。如果爲負數,則將該數的非標度值乘以 10 的負scale 次冪。因此,BigDecimal表示的數值是(unscaledValue × 10-scale)。
2、構造方法
構造 BigDecimal 對象常用以下方法:
- BigDecimal BigDecimal(double d); //不允許使用
- BigDecimal BigDecimal(String s); //常用,推薦使用
- static BigDecimal valueOf(double d); //常用,推薦使用
其中,
-
- double 參數的構造方法,不允許使用!!!因爲它不能精確的得到相應的值;
-
- String 構造方法是完全可預知的: 寫入 new BigDecimal(“0.1”) 將創建一個 BigDecimal,它正好等於預期的0.1; 因此,通常建議優先使用 String 構造方法;
-
- 靜態方法 valueOf(double val) 內部實現,仍是將 double 類型轉爲 String 類型; 這通常是將 double(或float)轉化爲 BigDecimal 的首選方法;
// 構造方法
public static void constrouct() {
// int類型
BigDecimal intBD = new BigDecimal(123);
System.out.println("intBD:" + intBD);// 123
// long類型
BigDecimal longBD = new BigDecimal(1234);
System.out.println("longBD:" + longBD);// 1234
// Integer類型
BigDecimal integerBD = new BigDecimal(new BigInteger("123"));
System.out.println("integer:" + integerBD);// 123
// Double類型 不推薦使用 精度不精確
BigDecimal doubleBD = new BigDecimal(123.45, MathContext.UNLIMITED);// MathContext.UNLIMITED:其設置具有無限精度算法所需值的MathContext 對象
System.out.println("doubleBD:" + doubleBD);// 123.4500000000000028421709430404007434844970703125
BigDecimal doubleBD2 = new BigDecimal(123.45, MathContext.DECIMAL32);//Decimal32 格式(即 7 個數字) 舍入模式爲 HALF_EVEN
System.out.println("doubleBD2:" + doubleBD2);// 123.4500
// 推薦靜態方法方式 可以double/float類型轉爲 String 類
BigDecimal staticValueOf = BigDecimal.valueOf(123.45);
System.out.println("staticValueOf: "+staticValueOf);// 123.45
// String類型
BigDecimal String1 = new BigDecimal("123.45");
System.out.println("String1:"+String1);// 123.45
BigDecimal String2 = new BigDecimal("-123.451",MathContext.UNLIMITED);
System.out.println("String2:"+String2);// -123.451
}
3、常用方法
- BigDecimal 類的 valueOf()方法源碼
public static BigDecimal valueOf(double val) {
return new BigDecimal(Double.toString(val));
}
- BigDecimal類的幾個常用方法
/**
* 求餘數
* 返回值爲 (this % divisor) 的 BigDecimal
*/
BigDecimal remainder(BigDecimal divisor);
/**
* 求相反數
* 返回值是 (-this) 的 BigDecimal
*/
BigDecimal negate();
/**
* 將此 BigDecimal 與指定的 BigDecimal 比較
* 根據此方法,值相等但具有不同標度的兩個 BigDecimal 對象(如,2.0 和 2.00)被認爲是相等的;
* 相對六個 boolean 比較運算符 (<, ==, >, >=, !=, <=) 中每一個運算符的各個方法,優先提供此方法;
* 建議使用以下語句執行上述比較:(x.compareTo(y) <op> 0), 其中 <op> 是六個比較運算符之一;
*
* 指定者:接口 Comparable<BigDecimal> 中的 compareTo
* 返回:當此 BigDecimal 在數字上小於、等於或大於 val 時,返回 -1、0 或 1
*/
int compareTo(BigDecimal val);
4、加減乘除
public static BigDecimal add(BigDecimal num1,BigDecimal num2){
BigDecimal add = num1.add(num2);
return add;
}
// 減法 num1-num2
public static BigDecimal subtract(BigDecimal num1,BigDecimal num2){
BigDecimal subtract = num1.subtract(num2);
return subtract;
}
// 乘法
public static BigDecimal mulpity(BigDecimal num1,BigDecimal num2){
BigDecimal subtract = num1.multiply(num2, MathContext.DECIMAL64);
// BigDecimal subtract = num1.multiply(num2);// 3.9483
return subtract;
}
// 除法 sacle爲精度
public static BigDecimal divide(BigDecimal num1,BigDecimal num2,int scale){
BigDecimal divide = num1.divide(num2, scale);
return divide;
}
綜合代碼
package com.math.bigdecimal;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.MathContext;
/**
*
* @Title: TestBigDecimal
* @Description: TODO(BigDecimal)
* @author X-Dragon
* @date 2018年12月21日 下午10:46:49
* @version V1.0
*
*/
public class TestBigDecimal {
// static BigDecimal bigDecimal3 = new BigDecimal(Double.valueOf(1.23)); //這種計算出來1.229999999999999982236431605997495353221893310546875
static BigDecimal bigDecimal1 = new BigDecimal(Double.toString(1.23));// 1.23
static BigDecimal bigDecimal2 = new BigDecimal(Double.toString(3.21));// 3.21
// 構造方法
public static void constrouct() {
// int類型
BigDecimal intBD = new BigDecimal(123);
System.out.println("intBD:" + intBD);// 123
// long類型
BigDecimal longBD = new BigDecimal(1234);
System.out.println("longBD:" + longBD);// 1234
// Integer類型
BigDecimal integerBD = new BigDecimal(new BigInteger("123"));
System.out.println("integer:" + integerBD);// 123
// Double類型 不推薦使用 精度不精確
BigDecimal doubleBD = new BigDecimal(123.45, MathContext.UNLIMITED);// MathContext.UNLIMITED:其設置具有無限精度算法所需值的MathContext 對象
System.out.println("doubleBD:" + doubleBD);// 123.4500000000000028421709430404007434844970703125
BigDecimal doubleBD2 = new BigDecimal(123.45, MathContext.DECIMAL32);//Decimal32 格式(即 7 個數字) 舍入模式爲 HALF_EVEN
System.out.println("doubleBD2:" + doubleBD2);// 123.4500
// 推薦靜態方法方式 可以double/float類型轉爲 String 類
BigDecimal staticValueOf = BigDecimal.valueOf(123.45);
System.out.println("staticValueOf: "+staticValueOf);// 123.45
// 推薦 Double封裝類轉換成string
BigDecimal bigDecimalDoubletoString = new BigDecimal(Double.toString(123.45d));
System.out.println("Double.toString(123.45d):" + bigDecimalDoubletoString);// Double.toString(123.45d): 123.45
// String類型
BigDecimal String1 = new BigDecimal("123.45");
System.out.println("String1:"+String1);// 123.45
BigDecimal String2 = new BigDecimal("-123.451",MathContext.UNLIMITED);
System.out.println("String2:"+String2);// -123.451
}
// 加法
public static BigDecimal add(BigDecimal num1,BigDecimal num2){
BigDecimal add = num1.add(num2);
return add;
}
// 減法 num1-num2
public static BigDecimal subtract(BigDecimal num1,BigDecimal num2){
BigDecimal subtract = num1.subtract(num2);
return subtract;
}
// 乘法
public static BigDecimal mulpity(BigDecimal num1,BigDecimal num2){
BigDecimal subtract = num1.multiply(num2, MathContext.DECIMAL64);
// BigDecimal subtract = num1.multiply(num2);// 3.9483
return subtract;
}
// 除法 sacle爲精度
public static BigDecimal divide(BigDecimal num1,BigDecimal num2,int scale){
BigDecimal divide = num1.divide(num2, scale);
return divide;
}
public static void main(String[] args) {
// constrouct();
System.out.println("前面的數字 "+bigDecimal1+"後面的數字 "+bigDecimal2);
System.out.println("add加法:"+add(bigDecimal1,bigDecimal2));
System.out.println("subtract減法:"+subtract(bigDecimal1,bigDecimal2));
System.out.println("mulpity乘法:"+mulpity(bigDecimal1,bigDecimal2));
System.out.println("divide除法精度爲2 :"+divide(bigDecimal1,bigDecimal2,2));
}
}