欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java中浮點(diǎn)數(shù)精度問題的解決方法

 更新時間:2016年10月01日 10:29:18   投稿:mrr  
這篇文章給大家介紹了Java中浮點(diǎn)數(shù)精度問題的解決方法,本文給大家介紹的非常詳細(xì),有問題描述有原因分析,非常不錯,具有參考借鑒價值,感興趣的朋友一起看看吧

問題描述

在項目中用Java做浮點(diǎn)數(shù)計算時,發(fā)現(xiàn)對于4.015*100這樣的計算,結(jié)果不是預(yù)料中的401.5,而是401.49999999999994。如此長的位數(shù),對于顯示來說很不友好。

問題原因:浮點(diǎn)數(shù)表示

查閱相關(guān)資料,發(fā)現(xiàn)原因是:計算機(jī)中的浮點(diǎn)數(shù)并不能完全精確表示。例如,對于一個double型的38414.4來說,計算機(jī)是這樣存儲它的:

轉(zhuǎn)成二進(jìn)制:1001011000001110.0110011001100110011001100110011001100
轉(zhuǎn)成科

學(xué)計數(shù)法:1.0010110000011100110011001100110011001100110011001100×2^15

double型編碼格式是這樣的:

double 符號位1位 階碼11位 尾數(shù)52位

符號位:正數(shù)統(tǒng)一是0

階碼:15是正數(shù),因此最高位是1,最低位減1,為10000001110

尾數(shù):去掉最高位默認(rèn)的1,為0010110000011100110011001100110011001100110011001100

組合起來,最終得到的編碼是:0 10000001110 0010110000011100110011001100110011001100110011001100

從這里可以看出來,主要原因在于二進(jìn)制編碼使得小數(shù)部分無法完全精確表示,例如0.4 = 0.25 + 0.125 + ...,只能無限接近。所以在對浮點(diǎn)數(shù)做計算時會產(chǎn)生精度誤差。

解決辦法:高精度

Java中的BigDecimal可以支持任意精度的浮點(diǎn)數(shù)運(yùn)算。在《Effective Java 》這本書中建議:float 和double 用來做科學(xué)計算或者是工程計算,而在商業(yè)計算中使用java.math.BigDecimal 。

BigDecimal有多種構(gòu)造方法,如BigDecimal(double),BigDecimal(String),需要注意的是:構(gòu)造參數(shù)為String類型時才能保證不丟失精度,因為double類型本身就是不完全精確的。故需要寫成這樣:BigDecimal("0.02")。

double類型的基本運(yùn)算都能在BigDecimal中找到相對應(yīng)的方法。另外,BigDecimal還可以配合NumberFormat做格式化輸出。

BigDecimal在做運(yùn)算的時候都會生成新的BigDecimal對象,因此相對double來說會帶來更多的性能開銷。

高精度實(shí)現(xiàn)初探

那么BigDecimal是如何做到能夠表示任意精度的呢?這里只做一個初步的分析。

首先看BigInteger的實(shí)現(xiàn)。普通的int型是32位,因此有范圍限制。BigInteger中有成員變量int[] mag,這樣變長的int數(shù)組使得表示任意大小的整數(shù)成為可能。

再看BigDecimal的實(shí)現(xiàn)。它的官方介紹中說,任意一個BigDecimal都可以表示為unscaledValue × 10^-scale的形式。unscaledValue是一個任意大小的整數(shù),在源代碼中對應(yīng)BigInteger intVal這個成員變量;scale是階數(shù),在源代碼中對應(yīng)int scale這個變量。這樣就在BigInteger的基礎(chǔ)上得到了BigDecimal的實(shí)現(xiàn)。

以上所述是小編給大家介紹的Java中浮點(diǎn)數(shù)精度問題的解決方法,希望對大家有所幫助,如果大家有任何疑問歡迎給我留言。

相關(guān)文章

最新評論