国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Java > 正文

Java中浮點數精度問題的解決方法

2019-11-26 13:45:42
字體:
來源:轉載
供稿:網友

問題描述

在項目中用Java做浮點數計算時,發現對于4.015*100這樣的計算,結果不是預料中的401.5,而是401.49999999999994。如此長的位數,對于顯示來說很不友好。

問題原因:浮點數表示

查閱相關資料,發現原因是:計算機中的浮點數并不能完全精確表示。例如,對于一個double型的38414.4來說,計算機是這樣存儲它的:

轉成二進制:1001011000001110.0110011001100110011001100110011001100
轉成科

學計數法:1.0010110000011100110011001100110011001100110011001100×2^15

double型編碼格式是這樣的:

double 符號位1位 階碼11位 尾數52位

符號位:正數統一是0

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

尾數:去掉最高位默認的1,為0010110000011100110011001100110011001100110011001100

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

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

解決辦法:高精度

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

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

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

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

高精度實現初探

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

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

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

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

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 汉寿县| 乐山市| 定日县| 新昌县| 大英县| 汉沽区| 盐亭县| 栖霞市| 江源县| 黎川县| 丰城市| 商都县| 阿城市| 三河市| 澎湖县| 安岳县| 谢通门县| 云林县| 崇左市| 南雄市| 西藏| 郯城县| 和田市| 汪清县| 松阳县| 临邑县| 田东县| 漾濞| 三河市| 木里| 景宁| 稷山县| 平泉县| 张家口市| 长丰县| 韩城市| 苏尼特右旗| 永安市| 鹿邑县| 和田县| 黔西县|