http://blog.csdn.net/shadow_zed/article/details/73522157
/*
* 使用BigDecimal需要注意的事項:
* 1、兩個BigDecimal值不能使用“ +, -, *, / ” 進行加減乘除,要使用“ add, substract, multiply, divide ”;
* 2、兩個BigDecimal值比較使用compareTo方法, 比較結果有-1, 0, 1, 分別表示小於, 等於, 大於; 對於0, 可以使用BigDecimal.ZERO表示;
* 3、提供(相對)精確的除法運算。當發生除不盡的情況時,由scale參數指 定精度,以后的數字四舍五入;
* 4、因double有效位數為 16位這就會出現存儲小數位數不夠的情況,這種情況下就會出現誤差,解決方法就是使用BigDecimal,它的有
效長度足夠長可存儲 小數位數因此可代替double來進行加減乘除, 金額必須是完全精確的計算, 故不能使用double或者float, 而
應該采用java.math.BigDecimal.
* 5、mysql數據庫設計
BigDecimal在進行入庫時, 數據庫選擇decimal類型, 長度可以自定義, 如18; 小數點我們項目中用的是2, 保留2位小數. 此外還要注意的就是默認值,
一定寫成0.00, 不要用默認的NULL, 否則在進行加減排序等操作時, 會帶來轉換的麻煩!
如 :`balance` decimal(18,2) DEFAULT '0.00' COMMENT '賬戶余額',
*/
package bigDecimalTest;
import java.math.BigDecimal;
/**
* 1、兩個BigDecimal值不能使用“ +, -, *, / ” 進行加減乘除,要使用“ add, substract, multiply, divide ”
* 2、兩個BigDecimal值比較使用compareTo方法, 比較結果有-1, 0, 1, 分別表示小於, 等於, 大於; 對於0, 可以使用BigDecimal.ZERO表示
*
*
*/
public class Arith {
private static final int DEF_DIV_SCALE = 10; // 這個類不能實例化
private Arith() {
}
/**
* 提供精確的加法運算。
*
* @param v1
* 被加數
* @param v2
* 加數
* @return 兩個參數的和
*/
public static double add(double v1, double v2) {
BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2));
return b1.add(b2).doubleValue();
}
/**
* 提供精確的減法運算。
*
* @param v1
* 被減數
* @param v2
* 減數
* @return 兩個參數的差
*/
public static double sub(double v1, double v2) {
BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2));
return b1.subtract(b2).doubleValue();
}
/**
* 使用double來進行測試
* @param v1
* @param v2
* @return
*/
public static double sub01(double v1, double v2) {
return v1-v2;
}
/**
* 提供精確的乘法運算。
*
* @param v1
* 被乘數
* @param v2
* 乘數
* @return 兩個參數的積
*/
public static double mul(double v1, double v2) {
BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2));
return b1.multiply(b2).doubleValue();
}
/**
* 提供(相對)精確的除法運算,當發生除不盡的情況時,精確到 小數點以后10位,以后的數字四舍五入。
*
* @param v1
* 被除數
* @param v2
* 除數
* @return 兩個參數的商
*/
public static double div(double v1, double v2) {
return div(v1, v2, DEF_DIV_SCALE);
}
/**
* 提供(相對)精確的除法運算。當發生除不盡的情況時,由scale參數指 定精度,以后的數字四舍五入。
*
* @param v1
* 被除數
* @param v2
* 除數
* @param scale
* 表示表示需要精確到小數點以后幾位。
* @return 兩個參數的商
*/
public static double div(double v1, double v2, int scale) {
if (scale < 0) {
throw new IllegalArgumentException(
"The scale must be a positive integer or zero");
}
BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2));
return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
}
/**
* 提供精確的小數位四舍五入處理。
*
* @param v
* 需要四舍五入的數字
* @param scale
* 小數點后保留幾位
* @return 四舍五入后的結果
*/
public static double round(double v, int scale) {
if (scale < 0) {
throw new IllegalArgumentException(
"The scale must be a positive integer or zero");
}
BigDecimal b = new BigDecimal(Double.toString(v));
BigDecimal one = new BigDecimal("1");
return b.divide(one, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
}
/**
* 因double有效位數為 16位這就會出現存儲小數位數不夠的情況,這種情況下就會出現誤差,解決方法就是使用BigDecimal,它的有
* 效長度足夠長可存儲 小數位數因此可代替double來進行加減乘除, 金額必須是完全精確的計算, 故不能使用double或者float, 而
* 應該采用java.math.BigDecimal.
* @param args
*/
public static void main(String[] args) {
//兩個BigDecimal值比較使用compareTo方法, 比較結果有-1, 0, 1, 分別表示小於, 等於, 大於;
//對於0, 可以使用BigDecimal.ZERO表示;如:bd.compareTo(BigDecimal.ZERO)
BigDecimal bd = new BigDecimal(3);
BigDecimal bd01 = new BigDecimal(3);
if(bd.compareTo(bd01) > 0){
System.out.println("bd > bd01");
}else if(bd.compareTo(bd01) < 0){
System.out.println("bd < bd01");
}else{
System.out.println("bd = bd01");
}
//減法測試
double s1 = sub(0.03, 0.02);
double s2 = sub01(0.03, 0.02);
System.out.println(s1 + "---" + s2);
// 0.01---0.009999999999999998
//除法測試
System.out.println(div(0.03, 0.022));
}
}