Double 計(jì)算的方式
public class NewDemo {
public static void main(String[] args) {
System.out.println(0.06+0.01);
System.out.println(1.0-0.32);
System.out.println(0.035*100);
System.out.println(3721.2/1000);
}
}
以上輸出的結(jié)果為:
0.06999999999999999
0.6799999999999999
3.5000000000000004
3.7211999999999996
你認(rèn)為你看錯(cuò)了晚缩,但結(jié)果卻是是這樣的尾膊。
問題在哪里呢?
原因在于我們的計(jì)算機(jī)是二進(jìn)制的荞彼。浮點(diǎn)數(shù)沒有辦法是用二進(jìn)制進(jìn)行精確表示冈敛。我們的CPU表示浮點(diǎn)數(shù)由兩個(gè)部分組成:指數(shù)和尾數(shù),這樣的表示方法一般都會(huì)失去一定的精確度鸣皂,有些浮點(diǎn)數(shù)運(yùn)算也會(huì)產(chǎn)生一定的誤差抓谴。
如:2.4的二進(jìn)制表示并非就是精確的2.4。反而最為接近的二進(jìn)制表示是 2.3999999999999999寞缝。浮點(diǎn)數(shù)的值實(shí)際上是由一個(gè)特定的數(shù)學(xué)公式計(jì)算得到的癌压。
其實(shí)java的float只能用來(lái)進(jìn)行科學(xué)計(jì)算或工程計(jì)算,在大多數(shù)的商業(yè)計(jì)算中荆陆,一般采用java.math.BigDecimal類來(lái)進(jìn)行精確計(jì)算滩届。
在使用BigDecimal類來(lái)進(jìn)行計(jì)算的時(shí)候,主要分為以下步驟:
- 用float或者double變量構(gòu)建BigDecimal對(duì)象被啼。
- 通過(guò)調(diào)用BigDecimal的加丐吓,減,乘趟据,除等相應(yīng)的方法進(jìn)行算術(shù)運(yùn)算券犁。
- 把BigDecimal對(duì)象轉(zhuǎn)換成float,double汹碱,int等類型粘衬。
一般來(lái)說(shuō),可以使用BigDecimal的構(gòu)造方法或者靜態(tài)方法的valueOf()方法把基本類型的變量構(gòu)建成BigDecimal對(duì)象咳促。
使用 bigdecimal 來(lái)計(jì)算
對(duì)于常用的加稚新,減,乘跪腹,除褂删,BigDecimal類提供了相應(yīng)的成員方法。
下面是一個(gè)工具類冲茸,該工具類提供加屯阀,減,乘轴术,除運(yùn)算难衰。
還有以當(dāng)前數(shù)據(jù)類型轉(zhuǎn) BigDecimal 類型的博客待續(xù).....
1. public BigDecimal add(BigDecimal value); //加法
2. public BigDecimal subtract(BigDecimal value); //減法
3. public BigDecimal multiply(BigDecimal value); //乘法
4. public BigDecimal divide(BigDecimal value); //除法
進(jìn)行相應(yīng)的計(jì)算后,我們可能需要將BigDecimal對(duì)象轉(zhuǎn)換成相應(yīng)的基本數(shù)據(jù)類型的變量逗栽,可以使用floatValue()盖袭,doubleValue()等方法。
public class BigDecimallDemo {
/**
* @Title: add
* @Description: 精確的加法運(yùn)算
* @Param: [value1, double2]
* @return: double
* @Author: MK monkey
* @Date: 2018/4/23 01:40
*/
public static double add(double double1, double double2) {
BigDecimal b1 = new BigDecimal(Double.valueOf(double1));
BigDecimal b2 = new BigDecimal(Double.valueOf(double2));
return b1.add(b2).doubleValue();
}
/**
* @Title: sub
* @Description: 精確的減法運(yùn)算
* @Param: [double1, double2]
* @return: double
* @Author: MK monkey
* @Date: 2018/4/23 01:42
*/
public static double sub(double double1, double double2) {
BigDecimal b1 = new BigDecimal(Double.valueOf(double1));
BigDecimal b2 = new BigDecimal(Double.valueOf(double2));
return b1.subtract(b2).doubleValue();
}
/**
* @Title: mul
* @Description: 精確的除法運(yùn)算
* @Param: [double1, double2]
* @return: double
* @Author: MK monkey
* @Date: 2018/4/23 01:43
*/
public static double mul(double double1, double double2) {
BigDecimal b1 = new BigDecimal(Double.valueOf(double1));
BigDecimal b2 = new BigDecimal(Double.valueOf(double2));
return b1.multiply(b2).doubleValue();
}
/**
* @Title: div
* @Description: 精確的除法運(yùn)算
* @Param: [double1, double2, scale]
* @return: double
* @Author: MK monkey
* @Date: 2018/4/23 01:43
*/
public static double div(double double1, double double2, int decimal) throws Exception {
// scale 為保留小數(shù)個(gè)數(shù) 不可低于0個(gè)
if (decimal < 0) {
throw new Exception("精確度不能小于0");
}
BigDecimal b1 = new BigDecimal(Double.valueOf(double1));
BigDecimal b2 = new BigDecimal(Double.valueOf(double2));
return b1.divide(b2, decimal).doubleValue();
}