不精確的情況:
public class BigDecimalDemo1 {
public static void main(String[] args) {
System.out.println(0.09 + 0.01); // 0.09999999999999999
System.out.println(0.216 - 0.1); // 0.11599999999999999
System.out.println(0.226 * 0.01); // 0.0022600000000000003
System.out.println(0.09 / 0.1); // 0.8999999999999999
}
}
有些小數可能有很多位:
圖1
浮點型別所佔用的位數是有限的:
圖2
如果浮點數的二進位制位數太多, 超過了位數的限制, 則只能捨棄, 從而導致資料不精確.
BigDecimal 所在的包: java.math
圖3
程式示例:
public class Demo {
public static void main(String[] args) {
/*
構造方法獲取 BigDecimal 物件
public BigDecimal(double val) public BigDecimal(string val)
靜態方法獲取 BigDecimal 物件
public static BigDecimal valuef(double val)
*/
// 1. 透過傳遞 double 型別的小數來建立物件
// 細節:
// 這種方式有可能是不精確的, 所以不建議使用
BigDecimal bd1 = new BigDecimal(0.01);
BigDecimal bd2 = new BigDecimal(0.09);
System.out.println(bd1); // 0.01000000000000000020816681711721685132943093776702880859375
System.out.println(bd2); // 0.0899999999999999966693309261245303787291049957275390625
// 透過傳遞字串表示的小數來建立物件
BigDecimal bd3 = new BigDecimal("0.01");
BigDecimal bd4 = new BigDecimal("0.09");
BigDecimal bd5 = bd3.add(bd4);
System.out.println(bd3); // 0.01
System.out.println(bd4); // 0.09
System.out.println(bd5); // 0.10
}
}
程式示例:
public class Demo {
public static void main(String[] args) {
/*
構造方法獲取 BigDecimal 物件
public BigDecimal(double val) public BigDecimal(string val)
靜態方法獲取 BigDecimal 物件
public static BigDecimal valuef(double val)
*/
// 3. 透過靜態方法獲取物件
// 細節:
// 1. 如果要表示的數字不大, 沒有超出 double 的取值範圍, 建議使用靜態方法
// 2. 如果要表示的數字比較大, 超出了 double 的取值範圍, 建議使用構造方法
// 3. 如果我們傳遞的是 0 ~ 10 之間的整數, 包含 0, 包含 10, 那麼方法會返回已經建立好的物件, 不會重新 new
BigDecimal bd6 = BigDecimal.valueOf(10.0);
BigDecimal bd7 = BigDecimal.valueOf(10.0);
System.out.println(bd6 == bd7); // false
BigDecimal bd66 = BigDecimal.valueOf(10);
BigDecimal bd77 = BigDecimal.valueOf(10);
System.out.println(bd66 == bd77); // true
}
}
引數為 double 的 valueOf() 方法:
引數為 long 的 valueOf() 方法:
檢視 ZERO_THROUGH_TEN 陣列:
BigDecimal 的成員方法:
程式示例:
import java.math.BigDecimal;
import java.math.RoundingMode;
public class Demo3 {
public static void main(String[] args) {
/*
public BigDecimal add(BigDecimal val) 加法
public BigDecimal subtract(BigDecimal val) 減法
public BigDecimal multiply(BigDecimal val) 乘法
public BigDecimal divide(BigDecimal val) 除法
public BigDecimal divide(BigDecimal val, 精確幾位, 舍入模式)除法
*/
// 1.加法
BigDecimal bd1 = BigDecimal.valueOf(10.);
BigDecimal bd2 = BigDecimal.valueOf(3.0);
BigDecimal bd3 = bd1.add(bd2);
System.out.println(bd3); // 12.0
// 2.減法
BigDecimal bd4 = bd1.subtract(bd2);
System.out.println(bd4); // 8.0
// 3.乘法
BigDecimal bd5 = bd1.multiply(bd2);
System.out.println(bd5); // 20.00
// 4.除法
BigDecimal bd6 = bd1.divide(bd2, 2, RoundingMode.HALF_UP); // 四捨五入
BigDecimal bd7 = bd1.divide(bd2, 2, BigDecimal.ROUND_HALF_UP);
System.out.println(bd6); // 3.33
System.out.println(bd7); // 3.33
}
}
用打斷點的方式檢視:
public class Demo4 {
public static void main(String[] args) {
BigDecimal bd1 = BigDecimal.valueOf(0.226);
BigDecimal bd2 = BigDecimal.valueOf(123.226);
BigDecimal bd3 = BigDecimal.valueOf(-1.5);
}
}
注意這些陣列是 byte 型別的.
BigDecimal 也是有上限的. 但是實際電腦記憶體是不可能達到這麼大的值的, 所以可以認為是無限大的.