最近在看項(xiàng)目中的各種計(jì)算,由于是金融方面的項(xiàng)目,觸及到日化,年化,利息,債轉(zhuǎn)這些和錢有關(guān)的計(jì)算很多,其中全部通過BigDecimal類進(jìn)行的運(yùn)算,之前觸及到的計(jì)算基本都用+、-、*、/等算術(shù)運(yùn)算符直接進(jìn)行數(shù)學(xué)運(yùn)算,數(shù)據(jù)類型1般用double就可以解決問題,但是如果要求完全精度時(shí)double就不適合了,由于double是在廣域數(shù)值范圍上提供較為精確的快速近似計(jì)算(只能處理16位有效數(shù))。
BigDecimal是Java在java.math包中提供的API類,主要用來對超過16位有效位的數(shù)進(jìn)行精確的運(yùn)算。雙精度浮點(diǎn)型變量double可以處理16位有效數(shù)。在實(shí)際利用中,需要對更大或更小的數(shù)進(jìn)行運(yùn)算和處理。float和double只能用來做科學(xué)計(jì)算或是工程計(jì)算,在商業(yè)計(jì)算中要用java.math.BigDecimal。
BigDecimal所創(chuàng)建的是對象,我們不能使用傳統(tǒng)的+、-、*、/等算術(shù)運(yùn)算符直接對其對象進(jìn)行數(shù)學(xué)運(yùn)算,而必須調(diào)用其相對應(yīng)的方法。方法中的參數(shù)也必須是BigDecimal的對象。下面來看BigDecimal的構(gòu)造方法。
BigDecimal(int)創(chuàng)建1個(gè)具有參數(shù)所指定整數(shù)值的對象。
BigDecimal(double)創(chuàng)建1個(gè)具有參數(shù)所指定雙精度值的對象。
BigDecimal(long)創(chuàng)建1個(gè)具有參數(shù)所指定長整數(shù)值的對象。
BigDecimal(String)創(chuàng)建1個(gè)具有參數(shù)所指定以字符串表示的數(shù)值的對象。
這里需要注意的是double類型的,先看1個(gè)實(shí)例:
輸出結(jié)果:
1、這里我們注意到參數(shù)為double類型是,構(gòu)造的BigDecimal值實(shí)際上等于1.100000000000000088817841970012523233890533447265625,而不是1.1,這是由于1.1沒法準(zhǔn)確地表示為double(或說對該情況,不能表示為任何有限長度的2進(jìn)制小數(shù))。
2、參數(shù)為String類型構(gòu)造的BigDecimal值正好等于原值1.1。因此,在我們構(gòu)造BigDecimal值時(shí)通常選擇參數(shù)為String類型的構(gòu)造方法。
3、當(dāng)double 必須用作BigDecimal的參數(shù)時(shí),可以先使用Double.toString(double)方法將double轉(zhuǎn)換為String,然后使用BigDecimal(String)構(gòu)造方法。再使用BigDecimal.valueOf(double)方法獲得值。
加減乘除最基本的運(yùn)算
BigDecimal add(BigDecimal augend) 加法運(yùn)算
BigDecimal subtract(BigDecimal subtrahend) 減法運(yùn)算
BigDecimal multiply(BigDecimal multiplicand) 乘法運(yùn)算
BigDecimal divide(BigDecimal divisor) 除法運(yùn)算
由于尋求高精度,我們使用BigDecimal,但是在進(jìn)行帶除法的運(yùn)算時(shí),并且結(jié)果需要保存有效位數(shù)的時(shí),可能會(huì)出現(xiàn)精度問題。那甚么時(shí)候會(huì)出現(xiàn)呢?
我們知道10除3是永久除不盡的,并且結(jié)果我們需要進(jìn)行格式化(保存有效位數(shù))
BigDecimal對象的精度沒有限制。對除不盡的除法運(yùn)算,比如10/3,divide方法將會(huì)拋出 java.lang.ArithmeticException毛病,所以除法運(yùn)算要盡可能使用divide(BigDecimal d, int scale, int roundMode)指定標(biāo)度和保存模式來避免異常。
scale,標(biāo)度,小數(shù)點(diǎn)保存的位數(shù)
roundMode,保存模式
BigDecimal.ROUND_DOWN:直接丟掉標(biāo)度之外的小數(shù)
BigDecimal.ROUND_UP:不管舍棄的小數(shù)是幾,都進(jìn)1
BigDecimal.ROUND_HALF_UP:最多見的4舍5入
還有其他的模式,可以直接去源碼里看。
來看實(shí)例計(jì)算:
value: 3.3333333333
value: 9.9999999999
由于第1步的除法指定了標(biāo)度和保存模式,我們得到的是1個(gè)近似值,已丟失了精度,在進(jìn)行后續(xù)的運(yùn)算中,精度已沒法保證,如何解決這類問題?應(yīng)當(dāng)把除法運(yùn)算放在全部運(yùn)算的最后,以減小除法帶來的精度問題。
商業(yè)計(jì)算對錢最敏感,1分1毫平時(shí)看來很小,但是放在million,billion中,every
hundred損失a cent,結(jié)果也是巨大的。學(xué)習(xí)亦是如此,每天學(xué)習(xí)1分,1年后取得的改變也是巨大的。
上一篇 poj1459,網(wǎng)絡(luò)流,最大流,多源點(diǎn)多匯點(diǎn)
下一篇 【原創(chuàng)】QT:編譯時(shí)出現(xiàn) “error: error writing to -: Invalid argument”錯(cuò)誤的解決