日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

使用 BigDecimal 进行浮点数运算

發布時間:2024/1/1 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 使用 BigDecimal 进行浮点数运算 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

BigDecimal 介紹

BigDecimal?可以實現對浮點數的運算,不會造成精度丟失。

通常情況下,大部分需要浮點數精確運算結果的業務場景(比如涉及到錢的場景)都是通過?BigDecimal?來做的。

《阿里巴巴 Java 開發手冊》中提到:浮點數之間的等值判斷,基本數據類型不能用 == 來比較,包裝數據類型不能用 equals 來判斷。

具體原因我們在上面已經詳細介紹了,這里就不多提了。

想要解決浮點數運算精度丟失這個問題,可以直接使用?BigDecimal?來定義浮點數的值,然后再進行浮點數的運算操作即可。

BigDecimal?a?=?new?BigDecimal("1.0"); BigDecimal?b?=?new?BigDecimal("0.9"); BigDecimal?c?=?new?BigDecimal("0.8");BigDecimal?x?=?a.subtract(b); BigDecimal?y?=?b.subtract(c);System.out.println(x.compareTo(y));//?0

BigDecimal 常見方法

創建

我們在使用?BigDecimal?時,為了防止精度丟失,推薦使用它的BigDecimal(String val)構造方法或者?BigDecimal.valueOf(double val)?靜態方法來創建對象。

《阿里巴巴 Java 開發手冊》對這部分內容也有提到,如下圖所示。

加減乘除

add?方法用于將兩個?BigDecimal?對象相加,subtract?方法用于將兩個?BigDecimal?對象相減。multiply?方法用于將兩個?BigDecimal?對象相乘,divide?方法用于將兩個?BigDecimal?對象相除。

BigDecimal?a?=?new?BigDecimal("1.0"); BigDecimal?b?=?new?BigDecimal("0.9"); System.out.println(a.add(b));//?1.9 System.out.println(a.subtract(b));//?0.1 System.out.println(a.multiply(b));//?0.90 System.out.println(a.divide(b));//?無法除盡,拋出?ArithmeticException?異常 System.out.println(a.divide(b,?2,?RoundingMode.HALF_UP));//?1.11

這里需要注意的是,在我們使用?divide?方法的時候盡量使用 3 個參數版本,并且RoundingMode?不要選擇?UNNECESSARY,否則很可能會遇到?ArithmeticException(無法除盡出現無限循環小數的時候),其中?scale?表示要保留幾位小數,roundingMode?代表保留規則。

public?BigDecimal?divide(BigDecimal?divisor,?int?scale,?RoundingMode?roundingMode)?{return?divide(divisor,?scale,?roundingMode.oldMode); }

保留規則非常多,這里列舉幾種:

public?enum?RoundingMode?{//?2.5?->?3?,?1.6?->?2//?-1.6?->?-2?,?-2.5?->?-3UP(BigDecimal.ROUND_UP),//?2.5?->?2?,?1.6?->?1//?-1.6?->?-1?,?-2.5?->?-2DOWN(BigDecimal.ROUND_DOWN),//?2.5?->?3?,?1.6?->?2//?-1.6?->?-1?,?-2.5?->?-2CEILING(BigDecimal.ROUND_CEILING),//?2.5?->?2?,?1.6?->?1//?-1.6?->?-2?,?-2.5?->?-3FLOOR(BigDecimal.ROUND_FLOOR),//?2.5?->?3?,?1.6?->?2//?-1.6?->?-2?,?-2.5?->?-3HALF_UP(BigDecimal.ROUND_HALF_UP),//...... }

大小比較

a.compareTo(b)?: 返回 -1 表示?a?小于?b,0 表示?a?等于?b?, 1 表示?a?大于?b。

BigDecimal?a?=?new?BigDecimal("1.0"); BigDecimal?b?=?new?BigDecimal("0.9"); System.out.println(a.compareTo(b));//?1

保留幾位小數

通過?setScale方法設置保留幾位小數以及保留規則。保留規則有挺多種,不需要記,IDEA 會提示。

BigDecimal?m?=?new?BigDecimal("1.255433"); BigDecimal?n?=?m.setScale(3,RoundingMode.HALF_DOWN); System.out.println(n);//?1.255

BigDecimal 等值比較問題

《阿里巴巴 Java 開發手冊》中提到:

BigDecimal?使用?equals()?方法進行等值比較出現問題的代碼示例:

BigDecimal?a?=?new?BigDecimal("1"); BigDecimal?b?=?new?BigDecimal("1.0"); System.out.println(a.equals(b));//false

這是因為?equals()?方法不僅僅會比較值的大小(value)還會比較精度(scale),而?compareTo()?方法比較的時候會忽略精度。

1.0 的 scale 是 1,1 的 scale 是 0,因此?a.equals(b)?的結果是 false。

compareTo()?方法可以比較兩個?BigDecimal?的值,如果相等就返回 0,如果第 1 個數比第 2 個數大則返回 1,反之返回-1。

BigDecimal?a?=?new?BigDecimal("1"); BigDecimal?b?=?new?BigDecimal("1.0"); System.out.println(a.compareTo(b));//0

總結

浮點數沒有辦法用二進制精確表示,因此存在精度丟失的風險。

不過,Java 提供了BigDecimal?來操作浮點數。BigDecimal?的實現利用到了?BigInteger?(用來操作大整數), 所不同的是?BigDecimal?加入了小數位的概念。

總結

以上是生活随笔為你收集整理的使用 BigDecimal 进行浮点数运算的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。