Java中BigDecimal類介紹及用法
阿新 • • 發佈:2018-01-20
exceptio decimal body ue4 mage oat 比較運算符 mod 乘法
3. 靜態方法 valueOf(double val) 內部實現,仍是將 double 類型轉為 String 類型; 這通常是將 double(或float)轉化為 BigDecimal 的首選方法;
Java中提供了大數字(超過16位有效位)的操作類,即 java.math.BinInteger 類和 java.math.BigDecimal 類,用於高精度計算.
其中 BigInteger 類是針對大整數的處理類,而 BigDecimal 類則是針對大小數的處理類.
BigDecimal 類的實現用到了 BigInteger類,不同的是 BigDecimal 加入了小數的概念.
float和Double只能用來做科學計算或者是工程計算;在商業計算中,對數字精度要求較高,必須使用 BigInteger 類和 BigDecimal 類,它支持任何精度的定點數,可以用它來精確計算貨幣值.
BigDecimal類創建的是對象,不能使用傳統的+、-、*、/等算術運算符直接對其進行數學運算,而必須調用其對應的方法.方法的參數也必須是BigDecimal類型的對象.
一、構造BigDecimal 對象常用方法
1、方法一
BigDecimal BigDecimal(double d); //不允許使用
2、方法二
BigDecimal BigDecimal(String s); //常用,推薦使用
3、方法三
static BigDecimal valueOf(double d); //常用,推薦使用
註意:
1. double 參數的構造方法,不允許使用!!!!因為它不能精確的得到相應的值,值會變大;
2. String 構造方法是完全可預知的: 寫入 new BigDecimal("0.1") 將創建一個 BigDecimal,它正好等於預期的0.1; 因此,通常建議優先使用 String 構造方法;
3. 靜態方法 valueOf(double val) 內部實現,仍是將 double 類型轉為 String 類型; 這通常是將 double(或float)轉化為 BigDecimal 的首選方法;
測試代碼如下:
package com.qiyuan.util; import java.math.BigDecimal; public class orderCode { public static void main(String[] args) { double d1 = 0.10334; double d2 = 1234.0; System.out.println("new BigDecimal("+d1+")=" + new BigDecimal(d1)); //此種方式絕對不允許!!!!! System.out.println("new BigDecimal("+d2+")=" + new BigDecimal(d2)); //此種方式絕對不允許!!!!! System.out.println(""); System.out.println("new BigDecimal(String.valueOf("+d1+"))=" + new BigDecimal(String.valueOf(d1))); System.out.println("new BigDecimal(String.valueOf("+d2+"))=" + new BigDecimal(String.valueOf(d2))); System.out.println(""); System.out.println("new BigDecimal(String.valueOf("+d1+"))=" + new BigDecimal(Double.toString(d1))); System.out.println("new BigDecimal(String.valueOf("+d2+"))=" + new BigDecimal(Double.toString(d2))); System.out.println(""); System.out.println("BigDecimal.valueOf("+d1+")=" + BigDecimal.valueOf(d1)); System.out.println("BigDecimal.valueOf("+d2+")=" + BigDecimal.valueOf(d2)); System.out.println(""); BigDecimal b1 = BigDecimal.valueOf(1); BigDecimal b2 = BigDecimal.valueOf(1.00000); System.out.println(b1.equals(b2)); System.out.println(b1.compareTo(b2)); } }
輸出如下:
new BigDecimal(0.10334)=0.10334000000000000130118138486068346537649631500244140625 new BigDecimal(1234.0)=1234 new BigDecimal(String.valueOf(0.10334))=0.10334 new BigDecimal(String.valueOf(1234.0))=1234.0 new BigDecimal(String.valueOf(0.10334))=0.10334 new BigDecimal(String.valueOf(1234.0))=1234.0 BigDecimal.valueOf(0.10334)=0.10334 BigDecimal.valueOf(1234.0)=1234.0 false 0
二、BigDecimal保留小數位
public static void main(String[] args) throws IllegalAccessException { BigDecimal decimal = new BigDecimal("1.12345"); System.out.println(decimal); BigDecimal setScale = decimal.setScale(4,BigDecimal.ROUND_HALF_DOWN); System.out.println(setScale); BigDecimal setScale1 = decimal.setScale(4,BigDecimal.ROUND_HALF_UP); System.out.println(setScale1); }
參數定義 ROUND_CEILING Rounding mode to round towards positive infinity. 向正無窮方向舍入 ROUND_DOWN Rounding mode to round towards zero. 向零方向舍入 ROUND_FLOOR Rounding mode to round towards negative infinity. 向負無窮方向舍入 ROUND_HALF_DOWN Rounding mode to round towards "nearest neighbor" unless both neighbors are equidistant, in which case round down. 向(距離)最近的一邊舍入,除非兩邊(的距離)是相等,如果是這樣,向下舍入, 例如1.55 保留一位小數結果為1.5 ROUND_HALF_EVEN Rounding mode to round towards the "nearest neighbor" unless both neighbors are equidistant, in which case, round towards the even neighbor. 向(距離)最近的一邊舍入,除非兩邊(的距離)是相等,如果是這樣,如果保留位數是奇數,使用ROUND_HALF_UP ,如果是偶數,使用ROUND_HALF_DOWN ROUND_HALF_UP Rounding mode to round towards "nearest neighbor" unless both neighbors are equidistant, in which case round up. 向(距離)最近的一邊舍入,除非兩邊(的距離)是相等,如果是這樣,向上舍入, 1.55保留一位小數結果為1.6 ROUND_UNNECESSARY Rounding mode to assert that the requested operation has an exact result, hence no rounding is necessary. 計算結果是精確的,不需要舍入模式 ROUND_UP Rounding mode to round away from zero. 向遠離0的方向舍入
附件1,BigDecimal 類的 valueOf()方法源碼
public static BigDecimal valueOf(double val) { return new BigDecimal(Double.toString(val)); }
附件2,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);
附件3,提供精確的浮點數運算(包括加、減、乘、除、四舍五入)的工具類源碼
package com.qiyuan.util; import java.math.BigDecimal; public class ArithUtil { // 除法運算默認精度 private static final int DEF_DIV_SCALE = 10; private ArithUtil() { } /** * 精確加法 */ public static double add(double value1, double value2) { BigDecimal b1 = BigDecimal.valueOf(value1); BigDecimal b2 = BigDecimal.valueOf(value2); return b1.add(b2).doubleValue(); } /** * 精確減法 */ public static double sub(double value1, double value2) { BigDecimal b1 = BigDecimal.valueOf(value1); BigDecimal b2 = BigDecimal.valueOf(value2); return b1.subtract(b2).doubleValue(); } /** * 精確乘法 */ public static double mul(double value1, double value2) { BigDecimal b1 = BigDecimal.valueOf(value1); BigDecimal b2 = BigDecimal.valueOf(value2); return b1.multiply(b2).doubleValue(); } /** * 精確除法 使用默認精度 */ public static double div(double value1, double value2) throws IllegalAccessException { return div(value1, value2, DEF_DIV_SCALE); } /** * 精確除法 * @param scale 精度 */ public static double div(double value1, double value2, int scale) throws IllegalAccessException { if(scale < 0) { throw new IllegalAccessException("精確度不能小於0"); } BigDecimal b1 = BigDecimal.valueOf(value1); BigDecimal b2 = BigDecimal.valueOf(value2); // return b1.divide(b2, scale).doubleValue(); return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).doubleValue(); } /** * 四舍五入 * @param scale 小數點後保留幾位 */ public static double round(double v, int scale) throws IllegalAccessException { return div(v, 1, scale); } /** * 比較大小 */ public static boolean equalTo(BigDecimal b1, BigDecimal b2) { if(b1 == null || b2 == null) { return false; } return 0 == b1.compareTo(b2); } public static void main(String[] args) throws IllegalAccessException { double value1=1.2345678912311; double value2=9.1234567890123; BigDecimal value3=new BigDecimal(Double.toString(value1)); BigDecimal value4=new BigDecimal(Double.toString(value2)); System.out.println("精確加法================="+ArithUtil.add(value1, value2)); System.out.println("精確減法================="+ArithUtil.sub(value1, value2)); System.out.println("精確乘法================="+ArithUtil.mul(value1, value2)); System.out.println("精確除法 使用默認精度 ================="+ArithUtil.div(value1, value2)); System.out.println("精確除法 設置精度================="+ArithUtil.div(value1, value2,20)); System.out.println("四舍五入 小數點後保留幾位 ================="+ArithUtil.round(value1, 10)); System.out.println("比較大小 ================="+ArithUtil.equalTo(value3, value4)); } }
Java中BigDecimal類介紹及用法