Java中使用BigDecimal進行浮點數(shù)運算
最近研究了一下Java的浮點數(shù)計算問題,從網(wǎng)上查詢了相關(guān)的資料,匯總并經(jīng)過了一些整理和調(diào)試,最后完成此文,歡迎大家指出其中的錯誤和問題。
在Java中,float聲明的變量是單精度浮點數(shù),double聲明的變量是雙精度浮點數(shù),顧名思義就是double型的實體占用內(nèi)存空間是float的兩倍。float是4個字節(jié)而double是8個字節(jié)。float和double類型的數(shù)據(jù),無法精確表示計算結(jié)果,這是由于float和double是不精確的計算。大家可以通過下面代碼可以看出來:
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);
}
}
運行的結(jié)果為:
0.060000000000000005
0.5800000000000001
401.49999999999994
1.2329999999999999
要想獲得理想的效果,我們可以嘗試使用java.text.DecimalFormat格式化浮點數(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
這是因為DecimalFormat是使用half-even 舍入(ROUND_HALF_EVEN),簡單的說就是向當四舍五入的5的時候向最近的偶數(shù)靠。所以使用DecimalForamt也無法得到可靠的浮點數(shù)。最后我們可以考慮使用BigDecimal來獲得更精確的計算:
BigDecimal提供了多個構(gòu)造函數(shù),和浮點數(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ù)來創(chuàng)建對象得到不精確的值,只有通過String來創(chuàng)建對象才是最準確的。
例如:
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來創(chuàng)建對象,這樣得到的結(jié)果才是最精確的。另外,如果是double數(shù),我們還可以使用:BigDecimal.valueOf(double val),原因很簡單,其JDK源碼如下所示:
public static BigDecimal valueOf(double val)
{
return new BigDecimal(Double.toString(val));
}
最后需要說明的是:BigDecimal的加減乘除其實最終都返回的是一個新的BigDecimal對象,因為BigDecimal是不可變的(immutable)的,在進行每一步運算時,都會產(chǎn)生一個新的對象,所以a.add(b);雖然做了加法操作,但是a并沒有保存加操作后的值,正確的用法應(yīng)該是a=a.add(b)。
相關(guān)文章
關(guān)于SSM框架下各層的解釋說明(Controller等)
這篇文章主要介紹了關(guān)于SSM框架下各層的解釋說明(Controller等),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-02-02
idea指定maven的settings文件不生效的問題解決
本文主要介紹了idea指定maven的settings文件不生效的問題解決,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-06-06
IDEA2023版本創(chuàng)建Spring項目只能勾選17和21卻無法使用Java8的完美解決方案
想創(chuàng)建一個springboot的項目,本地安裝的是1.8,但是在使用Spring Initializr創(chuàng)建項目時,發(fā)現(xiàn)版本只有17和21,這篇文章主要介紹了IDEA2023版本創(chuàng)建Sping項目只能勾選17和21,卻無法使用Java8的解決方法,需要的朋友可以參考下2023-12-12
Java BigDecimal解決double精度丟失的問題
我們在日常開發(fā)中, 有很多時候會遇到小數(shù)(double類型)精確計算,本文主要介紹了Java BigDecimal解決double精度丟失的問題,具有一定的參考價值,感興趣的可以了解一下2023-11-11
spring boot 不連接數(shù)據(jù)庫啟動的解決
這篇文章主要介紹了spring boot 不連接數(shù)據(jù)庫啟動的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-08-08

