bigdecimal不保留小数_金钱要使用BigDecimal数据类型(使用double的已经被公司开除了)...
生活随笔
收集整理的這篇文章主要介紹了
bigdecimal不保留小数_金钱要使用BigDecimal数据类型(使用double的已经被公司开除了)...
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
一:簡介
Java中的簡單浮點數類型float和double不能夠進行運算,或者運算會丟失精度,不光是Java,在其它很多編程語言中也有這樣的問題。在大多數情況下,計算的結果是準確的,float和double只能用來做科學計算或者是工程計算,在商業計算中我們要用 java.math.BigDecimal
// 浮點型計算不準確示例@Test
public void testDouble(){
// 0.060000000000000005
System.out.println(0.05+0.01);
// 0.5800000000000001
System.out.println(1.0-0.42);
// 401.49999999999994
System.out.println(4.015*100);
// 1.2329999999999999
System.out.println(123.3/100);
// 4.01 四舍五入保留兩位
System.out.println(Math.round(4.015*100)/100.0);
}
二:BigDecimal
BigDecimal有多種構造函數,常用的有2種,其中有一種不建議使用,就是double構造方式,建議使用String構造方式。
// 強制使用String的構造函數,double也有可能計算不太準確// 原則是使用BigDecimal并且一定要用String來夠造。
public BigDecimal(String val);
public BigDecimal(double val);BigDecimal也定義了幾個常用的值,0、1、10,靜態的,可以通過類名直接引用BigDecimal.ZERO
public static final BigDecimal ZERO = zeroThroughTen[0];
/**
* The value 1, with a scale of 0.
*
* @since 1.5
*/
public static final BigDecimal ONE = zeroThroughTen[1];
/**
* The value 10, with a scale of 0.
*
* @since 1.5
*/
public static final BigDecimal TEN = zeroThroughTen[10];
三:工具類
由于構造方法要用String對應的構造方法,如果我們要做一個加法運算,需要先將兩個浮點數轉為String,然后夠造成BigDecimal,在其中一個上調用add方法,傳入另一個作為參數,然后把運算的結果(BigDecimal)再轉換為浮點數。你能夠忍受這么煩瑣的過程嗎?下面我們提供一個工具類來簡化操作。
import java.math.BigDecimal;/**
* 由于Java的簡單類型不能夠精確的對浮點數進行運算,這個工具類提供精
* 確的浮點數運算,包括加減乘除和四舍五入。
*/
public class ArithUtil {
//默認除法運算精度
private static final int DEF_DIV_SCALE = 10;
/**
* 提供精確的加法運算。
* @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();
}
/**
* 提供精確的乘法運算。
* @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();
}
}
四:測試
@Testpublic void testBigDecimal(){
BigDecimal price = BigDecimal.ZERO;
// 通常建議優先使用(String)構造函數
BigDecimal amount = new BigDecimal("6.66");
// 0.06
System.out.println(ArithUtil.add(0.05, 0.01));
// 0.58
System.out.println(ArithUtil.sub(1.0, 0.42));
// 401.5
System.out.println(ArithUtil.mul(4.015, 100));
// 1.233
System.out.println(ArithUtil.div(123.3, 100));
// 4.02
System.out.println(ArithUtil.round(4.015, 2));
// BigDecimal 比較大小使用compareTo方法
// public int compareTo(BigDecimal val);
}
總結
以上是生活随笔為你收集整理的bigdecimal不保留小数_金钱要使用BigDecimal数据类型(使用double的已经被公司开除了)...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: openssl升级_CVE2020196
- 下一篇: imu与gps之间的时间戳_一个时间戳精