BigDecimal類
雙精度浮點型變量double可以處理16位有效數。在實際應用中,需要對更大或者更小的數進行運算和處理。Java在java.math包中提供的API類BigDecimal,用來對超過16位有效位的數進行精確的運算。表5.7中列出了BigDecimal類的主要構造器和方法。
表5.7 BigDecimal類的主要構造器和方法
構 造 器描 述
BigDecimal(int)創建一個具有參數所指定整數值的對象。
BigDecimal(double)創建一個具有參數所指定雙精度值的對象。
BigDecimal(long)創建一個具有參數所指定長整數值的對象。
BigDecimal(String)創建一個具有參數所指定以字符串表示的數值的對象。
續表
方 法描 述
abs() //返回其值是此BigInteger的絕對值的BigInteger。
add(BigInteger val) //返回其值為(this+val)的BigInteger。
subtract(BigInteger val) //返回其值為(this-val)的BigInteger。
multiply(BigInteger val) // 返回其值為(this*val)的BigInteger。
divide(BigInteger val) //返回其值為(this/val)的BigInteger。
remainder(BigInteger val) //返回其值為(this%val)的BigInteger。
compareTo(BigInteger val) //將此BigInteger與指定的BigInteger進行比較。返回值1、0、-1分別表示大於、等於、小於
pow(int exponent) //返回當前大數的exponent次冪。
toString() //返回此BigInteger的十進制字符串表示形式。
toString(int radix) //返回此BigInteger的給定基數(radix進制)的字符串表示形式。
注意,由於一般數值類型,例如double,不能准確地代表16位有效數以上的數字,在使用BigDecimal時,應用BigDecimal(String)構造器創建對象才有意義。另外,BigDecimal所創建的是對象,我們不能使用傳統的+、-、*、/等算術運算符直接對其對象進行數學運算,而必須調用其相對應的方法。方法中的參數也必須是BigDecimal的對象。
構造器是類的特殊方法,專門用來創建對象,特別是帶有參數的對象。關於構造器概念和編寫技術,將在本書第6章詳細介紹。
下面討論BigDecimal的一些常用例子:
//完整程序例子在本書配套資源目錄Ch5中名為BigDecimalTestApp.Java
//創建BigDecimal對象 BigDecimal bigNumber = new BigDecimal("89.1234567890123456789"); BigDecimal bigRate = new BigDecimal(1000); BigDecimal bigResult = new BigDecimal(); //對象bigResult的值為0.0 //對bigNumber的值乘以1000,結果 賦予bigResult bigResult = bigNumber.multiply(bigRate); System.out.println(bigResult.toString()); //或者System.out.println(bigResult); //顯示結果:89123.4567890123456789000 //以雙精度數返回bigNumber中的值 double dData = bigNumber.doublue(); System.out.println(dData); //結果:89.12345678901235
注意使用方法doublue()將對象bigNumber中的值以雙精度數值返回時,將丟失數據的准確性。使用其他方法,如xxxValue()時均存在這個問題,使用時必須慎重。
BigDecimal用來對超過16有效位以上的數值進行運算和操作。所有的算術運算都通過調用其相應的方法進行。 創建一個超過16有效位數的對象時,運用BigDecimal(String)才可避免丟失數字的精確度。
5.9 BigDecimal和格式化
由於NumberFormat類的format()方法可以使用BigDecimal對象作為其參數,可以利用BigDecimal對超出16位有效數字的貨幣值,百分值,以及一般數值進行格式化控制。
import java.math.BigDecimal; //引入這個包 double i = 3.856; // 舍掉小數取整 System.out.println("舍掉小數取整:Math.floor(3.856)=" + (int) Math.floor(i)); // 四舍五入取整 System.out.println("四舍五入取整:(3.856)=" + new BigDecimal(i).setScale(0, BigDecimal.ROUND_HALF_UP)); // 四舍五入保留兩位小數 System.out.println("四舍五入取整:(3.856)=" + new BigDecimal(i).setScale(2, BigDecimal.ROUND_HALF_UP)); // 湊整,取上限 System.out.println("湊整:Math.ceil(3.856)=" + (int) Math.ceil(i)); // 舍掉小數取整 System.out.println("舍掉小數取整:Math.floor(-3.856)=" + (int) Math.floor(-i)); // 四舍五入取整 System.out.println("四舍五入取整:(-3.856)=" + new BigDecimal(-i).setScale(0, BigDecimal.ROUND_HALF_UP)); // 四舍五入保留兩位小數 System.out.println("四舍五入取整:(-3.856)=" + new BigDecimal(-i).setScale(2, BigDecimal.ROUND_HALF_UP)); // 湊整,取上限 System.out.println("湊整(-3.856)=" + (int) Math.ceil(-i));
BigDecimal加減乘除
public static double add(double d1, double d2) { // 進行加法運算 BigDecimal b1 = new BigDecimal(d1); BigDecimal b2 = new BigDecimal(d2); return b1.add(b2).doubleValue(); } public static double sub(double d1, double d2) { // 進行減法運算 BigDecimal b1 = new BigDecimal(d1); BigDecimal b2 = new BigDecimal(d2); return b1.subtract(b2).doubleValue(); } public static double mul(double d1, double d2) { // 進行乘法運算 BigDecimal b1 = new BigDecimal(d1); BigDecimal b2 = new BigDecimal(d2); return b1.multiply(b2).doubleValue(); } public static double div(double d1, double d2, int len) {// 進行除法運算 BigDecimal b1 = new BigDecimal(d1); BigDecimal b2 = new BigDecimal(d2); return b1.divide(b2, len, BigDecimal.ROUND_HALF_UP).doubleValue(); } public static double round(double d, int len) { // 進行四舍五入操作 BigDecimal b1 = new BigDecimal(d); BigDecimal b2 = new BigDecimal(1); // 任何一個數字除以1都是原數字 // ROUND_HALF_UP是BigDecimal的一個常量,表示進行四舍五入的操作 return b1.divide(b2, len, BigDecimal.ROUND_HALF_UP).doubleValue(); }