為什么使用decmical
float 和 double都是浮點數,都有取值范圍, 都有精度范圍。 因此會經常出現下面問題,定義了一個浮點數,經過一系列的計算, 它本來應該等於某個確定值,但實際上並不是。。。???
計算機進行的是二進制運算,我們輸入的十進制數字會先轉換成二進制,進行運算后再轉換為十進制輸出。float / double相減會轉換成二進制,因float有效數字8位, double有效位數為16位,這就會出現存儲小數位數不夠的情況,這種情況下就會出現誤差,解決方法就是使用BigDecimal,它的有效長度足夠長,因此可代替float / double來進行加減乘除。
金融相關的開發中,金額必須是完全精確的計算,double 和 float 提供了快速的運算,然而問題在於轉換為二進制的時候,有些數字不能完全轉換,只能無限接近於原本的值,這就導致了你看到的不正確的結果,故不能使用double或者float,而應該采用java.math.BigDecimal。
decimal
decimal(18,0) 18是定點精度,0是小數位數。
decimal(a,b) a指定指定小數點左邊和右邊可以存儲的十進制數字的最大個數,最大精度38。
b指定小數點右邊可以存儲的十進制數字的最大個數。小數位數必須是從 0 到 a之間的值。默認小數位數是 0。
BigDecimal
Java在java.math包中提供的API類BigDecimal,用來對超過16位有效位的數進行精確的運算。雙精度浮點型變量double可以處理16位有效數。在實際應用中,需要對更大或者更小的數進行運算和處理。float和double只能用來做科學計算或者是工程計算,在商業計算中要用java.math.BigDecimal。BigDecimal所創建的是對象,我們不能使用傳統的+、-、*、/等算術運算符直接對其對象進行數學運算,而必須調用其相對應的方法。方法中的參數也必須是BigDecimal的對象。構造器是類的特殊方法,專門用來創建對象,特別是帶有參數的對象。
BigDecimal的四則運算
BigDecimal a = new BigDecimal("123");
BigDecimal b = new BigDecimal("456");
BigDecimal c = a.add(b);// 加
BigDecimal d = a.subtract(b);// 減
BigDecimal e = a.multiply(b);// 乘
// 除
// 參數2:指定精度,保留6位小數 ; 參數3: 選擇舍入模式,此處為 四舍五入BigDecimal f = a.divide(b, 6, BigDecimal.ROUND_HALF_UP);
// jdk 1.9中第三個參數 被RoundingMode取代
BigDecimal f = a.divide(b,RoundingMode.DOWN);//舍棄小數位
BigDecimal f = a.divide(b,2,RoundingMode.HALF_DOWN );//2位小數;舍入模式為大於0.5進1,否則舍棄。
注: BigDecimal的除法,需要指定計算答案的精度, 不然計算機不知道你的精度為多少,會拋異常的。
Exception in thread “main” java.lang.ArithmeticException
BigDecimal 的 signum() 方法 : 返回此 BigDecimal 的正負號。
//返回 1 表示值 為正值 ; 0 表示 為 0 ; -1 表示 負數 。 BigDecimal a = new BigDecimal("123"); int b = a.signum(); // 結果是 1 BigDecimal 的 compareTo()方法 , 比較大小 ; (不能直接使用算數運算符 == ,>, < 比較) // 結果 : 1 表示 大於; 0 表示 等於; -1 表示 小於 . BigDecimal a = new BigDecimal(0.5); BigDecimal b = new BigDecimal(0.2); int c = a.compareTo(b); // 結果 C = 1
參考https://blog.csdn.net/diyu122222/article/details/76887382
參考 https://blog.csdn.net/u014010512/article/details/91492380