Java中使用BigDecimal進(jìn)行浮點(diǎn)數(shù)運(yùn)算
最近研究了一下Java的浮點(diǎn)數(shù)計(jì)算問(wèn)題,從網(wǎng)上查詢了相關(guān)的資料,匯總并經(jīng)過(guò)了一些整理和調(diào)試,最后完成此文,歡迎大家指出其中的錯(cuò)誤和問(wèn)題。
在Java中,float聲明的變量是單精度浮點(diǎn)數(shù),double聲明的變量是雙精度浮點(diǎn)數(shù),顧名思義就是double型的實(shí)體占用內(nèi)存空間是float的兩倍。float是4個(gè)字節(jié)而double是8個(gè)字節(jié)。float和double類(lèi)型的數(shù)據(jù),無(wú)法精確表示計(jì)算結(jié)果,這是由于float和double是不精確的計(jì)算。大家可以通過(guò)下面代碼可以看出來(lái):
public class Test
{
public static void main(String[] args)
{
System.out.println(0.05 + 0.01);
System.out.println(1.0 - 0.42);
System.out.println(4.015 * 100);
System.out.println(123.3 / 100);
}
}
運(yùn)行的結(jié)果為:
0.060000000000000005
0.5800000000000001
401.49999999999994
1.2329999999999999
要想獲得理想的效果,我們可以嘗試使用java.text.DecimalFormat格式化浮點(diǎn)數(shù):
DecimalFormat可以按照一定的格式格式化數(shù)字,常用的格式化字符是#、0等。例:
System.out.println(new java.text.DecimalFormat("0.00").format(3.125));
System.out.println(new java.text.DecimalFormat("0.00").format(3.135));
但是得到的結(jié)果是:
3.12
3.14
這是因?yàn)镈ecimalFormat是使用half-even 舍入(ROUND_HALF_EVEN),簡(jiǎn)單的說(shuō)就是向當(dāng)四舍五入的5的時(shí)候向最近的偶數(shù)靠。所以使用DecimalForamt也無(wú)法得到可靠的浮點(diǎn)數(shù)。最后我們可以考慮使用BigDecimal來(lái)獲得更精確的計(jì)算:
BigDecimal提供了多個(gè)構(gòu)造函數(shù),和浮點(diǎn)數(shù)有關(guān)的有:
BigDecimal(double val) Translates a double into a BigDecimal.
BigDecimal(String val) Translates the String repre sentation of a BigDecimal into a BigDecimal.
但是用double參數(shù)來(lái)創(chuàng)建對(duì)象得到不精確的值,只有通過(guò)String來(lái)創(chuàng)建對(duì)象才是最準(zhǔn)確的。
例如:
BigDecimal bd1=new BigDecimal(0.05);
System.out.println(bd1.toString());
BigDecimal bd2=new BigDecimal("0.05");
System.out.println(bd2.toString());
得到結(jié)果:
0.05000000000000000277555756156289135105907917022705078125
0.05
所以,我們最終需要使用String來(lái)創(chuàng)建對(duì)象,這樣得到的結(jié)果才是最精確的。另外,如果是double數(shù),我們還可以使用:BigDecimal.valueOf(double val),原因很簡(jiǎn)單,其JDK源碼如下所示:
public static BigDecimal valueOf(double val)
{
return new BigDecimal(Double.toString(val));
}
最后需要說(shuō)明的是:BigDecimal的加減乘除其實(shí)最終都返回的是一個(gè)新的BigDecimal對(duì)象,因?yàn)锽igDecimal是不可變的(immutable)的,在進(jìn)行每一步運(yùn)算時(shí),都會(huì)產(chǎn)生一個(gè)新的對(duì)象,所以a.add(b);雖然做了加法操作,但是a并沒(méi)有保存加操作后的值,正確的用法應(yīng)該是a=a.add(b)。
- Java使用BigDecimal精確運(yùn)算浮點(diǎn)數(shù)
- java.math包下計(jì)算浮點(diǎn)數(shù)和整數(shù)的類(lèi)的實(shí)例
- Java判斷字符串是否是整數(shù)或者浮點(diǎn)數(shù)的方法
- JAVA浮點(diǎn)數(shù)計(jì)算精度損失底層原理與解決方案
- Java中浮點(diǎn)數(shù)精度問(wèn)題的解決方法
- java大數(shù)乘法的簡(jiǎn)單實(shí)現(xiàn) 浮點(diǎn)數(shù)乘法運(yùn)算
- java實(shí)現(xiàn)浮點(diǎn)數(shù)轉(zhuǎn)人民幣的小例子
- Java中的浮點(diǎn)數(shù)分析
- Java正確比較浮點(diǎn)數(shù)的方法
相關(guān)文章
springboot+gradle 構(gòu)建多模塊項(xiàng)目的步驟
這篇文章主要介紹了springboot+gradle 構(gòu)建多模塊項(xiàng)目的步驟,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-05-05Java Metrics系統(tǒng)性能監(jiān)控工具的使用詳解
Metrics是一個(gè)Java庫(kù),可以對(duì)系統(tǒng)進(jìn)行監(jiān)控,統(tǒng)計(jì)一些系統(tǒng)的性能指標(biāo)。本文就來(lái)和大家詳細(xì)聊聊這個(gè)工具的具體使用,希望對(duì)大家有所幫助2022-11-11可視化定時(shí)任務(wù)quartz集成解析全過(guò)程
在開(kāi)發(fā)中有很多定時(shí)任務(wù)都不是寫(xiě)死的而是可以人為配置并且寫(xiě)到數(shù)據(jù)庫(kù)中的,下面這篇文章主要給大家介紹了關(guān)于可視化定時(shí)任務(wù)quartz集成解析的相關(guān)資料,需要的朋友可以參考下2022-10-10java網(wǎng)絡(luò)編程之識(shí)別示例 獲取主機(jī)網(wǎng)絡(luò)接口列表
一個(gè)客戶端想要發(fā)起一次通信,先決條件就是需要知道運(yùn)行著服務(wù)器端程序的主機(jī)的IP地址是多少。然后我們才能夠通過(guò)這個(gè)地址向服務(wù)器發(fā)送信息。2014-01-01Java實(shí)現(xiàn)學(xué)生管理系統(tǒng)(IO版)
這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)學(xué)生管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-02-02