日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

詳解java中BigDecimal精度問題

瀏覽:30日期:2022-08-12 18:33:16
一、背景

在實際開發中,對于 不需要任何準確計算精度的屬性可以直接使用float或double,但是如果需要精確計算結果,則必須使用BigDecimal,例如價格、質量。

為什么這么說,主要有兩點

1、double計算會有精度丟失問題

2、在除法運算時,BigDecimal提供了豐富的取舍規則。(double雖然可以通過NumberFormat進行四舍五入,但是NumberFormat是線程不安全的)

對于精度問題我們可以看下實際的例子

public static void main(String[] args) { //正常 3.3 System.out.println('加法結果:'+(1.1+2.2)); //正常 -7.9 System.out.println('減法結果:'+(2.2-10.1)); //正常 2.42 System.out.println('乘法結果:'+(1.1*2.2)); //正常 0.44 System.out.println('除法結果:'+(4.4/10));}

實際控制臺輸出

詳解java中BigDecimal精度問題

為什么會這樣

在于我們的計算機是二進制的。浮點數沒有辦法是用二進制進行精確表示。我們的CPU表示浮點數由兩個部分組成:指數和尾數,這樣的表示方法一般都會

失去一定的精確度,有些浮點數運算也會產生一定的誤差。如:2.4的二進制表示并非就是精確的2.4。反而最為接近的二進制表示是 2.3999999999999999。

浮點數的值實際上是由一個特定的數學公式計算得到的。

二、BigDecimal構造函數1、四種構造函數

BigDecimal(int) //創建一個具有參數所指定整數值的對象。BigDecimal(double) //創建一個具有參數所指定雙精度值的對象。BigDecimal(long) //創建一個具有參數所指定長整數值的對象。BigDecimal(String) //創建一個具有參數所指定以字符串表示的數值的對象。

這幾個都是常用的構造器,他們返回的對象都是BigDecimal對象。換而言之,將BigDecimal對象轉換為其他類型的對象,我們通過以下幾種。

toString() //將BigDecimal對象的數值轉換成字符串。doubleValue() //將BigDecimal對象中的值以雙精度數返回。floatValue()//將BigDecimal對象中的值以單精度數返回。longValue() //將BigDecimal對象中的值以長整數返回。intValue() //將BigDecimal對象中的值以整數返回。

這里需要非常注意BigDecimal(double)的構造函數,也是會存在精度丟失的問題,其它的不會,這里也可以舉例說明

public static void main(String[] args) { BigDecimal intDecimal = new BigDecimal(10); BigDecimal doubleDecimal = new BigDecimal(4.3); BigDecimal longDecimal = new BigDecimal(10L); BigDecimal stringDecimal = new BigDecimal('4.3'); System.out.println('intDecimal=' + intDecimal); System.out.println('doubleDecimal=' + doubleDecimal); System.out.println('longDecimal=' + longDecimal); System.out.println('stringDecimal=' + stringDecimal);}

控制臺實際輸出

詳解java中BigDecimal精度問題

從圖中很明顯可以看出,對于double的構造函數是會存在精度丟失的可能的。

2、為什么會出現這種情況

這個在new BigDecimal(double)類型的構造函數上的注解有解釋說明。

這個構造函數的結果可能有些不可預測。 可以假設在Java中寫入new BigDecimal(0.1)創建一個BigDecimal ,它完全等于0.1(非標尺值為1,比例為1),但實際上等于

0.1000000000000000055511151231257827021181583404541015625。 這是因為0.1不能像double (或者作為任何有限長度的二進制分數)精確地表示。

因此,正在被傳遞給構造的值不是正好等于0.1。

3、如何解決

有兩種常用的解決辦法。

1、是將double 通過Double.toString(double)先轉為String,然后放入BigDecimal的String構造函數中。

2、不通過BigDecimal的構造函數,而是通過它的靜態方法BigDecimal.valueOf(double),也同樣不會丟失精度。

示例

public static void main(String[] args) { String string = Double.toString(4.3); BigDecimal stringBigDecimal = new BigDecimal(string); BigDecimal bigDecimal = BigDecimal.valueOf(4.3); System.out.println('stringBigDecimal = ' + stringBigDecimal); System.out.println('bigDecimal = ' + bigDecimal);}

運行結果

詳解java中BigDecimal精度問題

這樣也能保證,對與double而言,轉BigDecimal不會出現精度丟失的情況。

三、常用方法1、常用方法

示例

public static void main(String[] args) { BigDecimal a = new BigDecimal('4.5'); BigDecimal b = new BigDecimal('1.5'); BigDecimal c = new BigDecimal('-10.5'); BigDecimal add_result = a.add(b); BigDecimal subtract_result = a.subtract(b); BigDecimal multiply_result = a.multiply(b); BigDecimal divide_result = a.divide(b); BigDecimal remainder_result = a.remainder(b); BigDecimal max_result = a.max(b); BigDecimal min_result = a.min(b); BigDecimal abs_result = c.abs(); BigDecimal negate_result = a.negate(); System.out.println('4.5+1.5=' + add_result); System.out.println('4.5-1.5=' + subtract_result); System.out.println('4.5*1.5=' + multiply_result); System.out.println('4.5/1.5=' + divide_result); System.out.println('4.5/1.5余數=' + remainder_result); System.out.println('4.5和1.5最大數=' + max_result); System.out.println('4.5和1.5最小數=' + min_result); System.out.println('-10.5的絕對值=' + abs_result); System.out.println('4.5的相反數=' + negate_result);}

4.5+1.5=6.0

4.5-1.5=3.0

4.5*1.5=6.75

4.5/1.5=3

4.5/1.5余數=0.0

4.5和1.5最大數=4.5

4.5和1.5最小數=1.5

-10.5的絕對值=10.5

4.5的相反數=-4.5

這里把除法單獨再講一下,因為除法操作的時候會有除不盡的情況,,比如 3,5/3,這時會報錯java.lang.ArithmeticException: Non-terminating decimal expansion;

no exact representable decimal result。所以這里要考慮除不盡的情況下,保留幾位小數,取舍規則。(除法如果可能存在除不進,那就用下面方法)

BigDecimal divide(BigDecimal divisor, int scale, int roundingMode) 第一參數表示除數,第二個參數表示小數點后保留位數,第三個參數表示取舍規則。2、取舍規則

ROUND_UP //不管保留數字后面是大是小(0除外)都會進1ROUND_DOWN//保留設置數字,后面所有直接去除ROUND_HALF_UP //常用的四舍五入 ROUND_HALF_DOWN //五舍六入ROUND_CEILING //向正無窮方向舍入ROUND_FLOOR //向負無窮方向舍入ROUND_HALF_EVEN //向(距離)最近的一邊舍入,除非兩邊(的距離)是相等,如果是這樣,如果保留位數是奇數,使用ROUND_HALF_UP,如果是偶數,使用ROUND_HALF_DOWNROUND_UNNECESSARY //計算結果是精確的,不需要舍入模式

注意 我們最常用的應該是 ROUND_HALF_UP(四舍五入)

這里舉幾個常用的取舍規則

public static void main(String[] args) { BigDecimal a = new BigDecimal('1.15'); BigDecimal b = new BigDecimal('1'); //不管保留數字后面是大是小(0除外)都會進1 所以這里輸出為1.2 BigDecimal divide_1 = a.divide(b,1,BigDecimal.ROUND_UP); //保留設置數字,后面所有直接去除 所以這里輸出為1.1 BigDecimal divide_2 = a.divide(b,1,BigDecimal.ROUND_DOWN); //常用的四舍五入 所以這里輸出1.2 BigDecimal divide_3 = a.divide(b,1,BigDecimal.ROUND_HALF_UP); //這個可以理解成五舍六入 所以這里輸出1.1 BigDecimal divide_4 = a.divide(b,1,BigDecimal.ROUND_HALF_DOWN); //這里將1.15改成1.16 BigDecimal c = new BigDecimal('1.16'); //那么這里就符合六入了 所以輸出變為1.2 BigDecimal divide_5 = c.divide(b,1,BigDecimal.ROUND_HALF_DOWN); System.out.println('divide_1 = ' + divide_1); System.out.println('divide_2 = ' + divide_2); System.out.println('divide_3 = ' + divide_3); System.out.println('divide_4 = ' + divide_4); System.out.println('divide_5 = ' + divide_5);}

運行結果

divide_1 = 1.2

divide_2 = 1.1

divide_3 = 1.2

divide_4 = 1.1

divide_5 = 1.2

四、格式化

由于NumberFormat類的format()方法可以使用BigDecimal對象作為其參數,可以利用BigDecimal對超出16位有效數字的貨幣值,百分值,以及一般數值進行格式化控制。

以利用BigDecimal對貨幣和百分比格式化為例。首先,創建BigDecimal對象,進行BigDecimal的算術運算后,分別建立對貨幣和百分比格式化的引用,最后利用

BigDecimal對象作為format()方法的參數,輸出其格式化的貨幣值和百分比。

示例

public static void main(String[] args) { //建立貨幣格式化引用 NumberFormat currency = NumberFormat.getCurrencyInstance(); //建立百分比格式化引用 NumberFormat percent = NumberFormat.getPercentInstance(); //百分比小數點最多3位 percent.setMaximumFractionDigits(3); //取整 NumberFormat integerInstance = NumberFormat.getIntegerInstance(); ////金額 BigDecimal loanAmount = new BigDecimal('188.555'); ////利率 BigDecimal interestRate = new BigDecimal('0.018555555'); //沒有指定保留位數的情況下 默認保留2位 System.out.println('金額: ' + currency.format(loanAmount)); //貨幣(百分比)格式化 指定默認的取舍規則是四舍五入 System.out.println('利率: ' + percent.format(interestRate)); //取整還有點不一樣 188.555取整為189, 188.51也是189 但是189.5確實188,所以它不是真正意義上的四舍五入 System.out.println('取整: ' + integerInstance.format(loanAmount));}

運行結果

金額: ¥188.56利率: 1.856%取整: 189

這里有幾點在說明下

1、格式化的時候沒有指定保留位數的情況下 默認保留2位。

2、貨幣(百分比)格式化 指定默認的取舍規則是四舍五入。

3、取整還有點不一樣 188.555取整為189, 188.51也是189 但是189.5確實188,所以它不是真正意義上的四舍五入。

以上就是詳解java中BigDecimal精度問題的詳細內容,更多關于java的資料請關注好吧啦網其它相關文章!

標簽: Java
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
日韩一区精品| 国产精品人人爽人人做我的可爱| 精品一区二区三区中文字幕在线| 日本91福利区| 久久不卡日韩美女| 99久久激情| 奶水喷射视频一区| 欧美国产不卡| 欧美99久久| 国产亚洲精品美女久久 | 国产精品嫩模av在线| 国产一区二区三区四区| 亚洲精品va| 久久精品一区二区三区中文字幕| 免费视频一区二区三区在线观看| 国产一区国产二区国产三区| 热久久免费视频| 精品一区二区男人吃奶 | 男女男精品视频网| 欧美一级全黄| 成人亚洲一区二区| 不卡一区2区| 偷拍欧美精品| 婷婷久久免费视频| 丝袜av一区| 在线一区欧美| 国产美女久久| 亚洲一本视频| 麻豆国产91在线播放| 国产黄大片在线观看| 日韩国产精品久久久| 精品久久美女| 天堂成人免费av电影一区 | 视频精品一区| 一本大道色婷婷在线| 亚洲精品伊人| 久久尤物视频| 亚洲免费中文| 国产+成+人+亚洲欧洲在线| 视频在线在亚洲| а√天堂8资源中文在线| 亚洲区第一页| 在线日韩电影| 欧美黄色精品| 亚洲永久精品唐人导航网址| 91精品蜜臀一区二区三区在线 | 国产成人在线中文字幕| 免费国产自久久久久三四区久久| 欧美日韩xxxx| 91久久久久| 欧美gv在线| 麻豆视频在线观看免费网站黄| 亚洲中午字幕| 欧美aa在线观看| 久久三级毛片| 青草国产精品| 免费视频一区二区| 久久久影院免费| 国精品产品一区| 日韩不卡在线观看日韩不卡视频| 久久亚洲精品中文字幕蜜潮电影| 欧美精品二区| 亚洲另类av| 国产99久久久国产精品成人免费| 另类小说一区二区三区| 日韩精品视频网站| 夜久久久久久| 欧美午夜精彩| 日韩大片免费观看| 久久免费视频66| 国产精品视频3p| 欧美一区二区三区久久| 亚洲综合二区| 午夜在线一区| 午夜欧美精品| 国产网站在线| 国产 日韩 欧美 综合 一区| 日韩高清电影免费| 视频在线观看一区| 一本色道久久精品| 自由日本语亚洲人高潮| аⅴ资源天堂资源库在线| 久久av综合| 国产欧美欧美| 国产精品亲子伦av一区二区三区| 91亚洲无吗| 欧美亚洲色图校园春色| 婷婷综合国产| 久久黄色影视| 欧美精品91| 成人在线视频免费| 成人精品高清在线视频| 精品国产黄a∨片高清在线| 国产精品久一| 欧美精品成人| 国产+成+人+亚洲欧洲在线| 福利一区和二区| 特黄毛片在线观看| 99精品美女| 九一成人免费视频| 99日韩精品| 蜜臀av性久久久久蜜臀aⅴ流畅 | 免费精品一区| 精品网站999| 精品国产黄a∨片高清在线| 久久久久免费| 亚洲a在线视频| 国产综合精品| 伊人久久一区| 国产精品欧美日韩一区| 国产一区二区三区探花| 91精品一区二区三区综合| 亚洲夜间福利| 综合激情一区| 国产精品入口久久| 四虎国产精品免费观看| 欧洲一级精品| 免费美女久久99| 欧美精品观看| 欧美xxxx中国| 美女久久久久| 日本午夜精品久久久| 精品日韩在线| 欧美日韩国产精品一区二区亚洲| 亚洲综合色婷婷在线观看| 日韩精品视频网| 国产一二在线播放| 久久午夜精品一区二区| 国产精品天堂蜜av在线播放| 亚洲天堂资源| 热久久免费视频| 精品久久福利| 女同性一区二区三区人了人一| 亚久久调教视频| 麻豆国产欧美一区二区三区 | 91久久精品无嫩草影院| 国内自拍视频一区二区三区| 五月天久久久| 国产日韩一区二区三区在线| 亚洲精品国产嫩草在线观看| 亚洲图片久久| 欧美国产偷国产精品三区| 视频在线观看国产精品| 精品色999| 亚洲欧美一级| 亚洲精品国产嫩草在线观看| 日韩中文字幕| 精品国产18久久久久久二百| 国产一区白浆| 91亚洲一区| 日本va欧美va瓶| 欧美特黄一级大片| 久久99精品久久久久久园产越南| 午夜精品免费| 色婷婷亚洲mv天堂mv在影片| 视频一区日韩精品| 精品欧美一区二区三区在线观看| 亚洲精品亚洲人成在线观看| 久久久噜噜噜| 欧美激情精品| 亚洲青青久久| 免费精品国产的网站免费观看| 日本午夜精品一区二区三区电影| 亚洲不卡av不卡一区二区| 国产高清日韩| 亚洲最新av| 精品一区三区| 日韩视频网站在线观看| 欧美中文高清| 免费看黄色91| 亚洲高清不卡| 福利欧美精品在线| 欧美日韩一区自拍| 日韩中文字幕亚洲一区二区va在线 | 天堂av在线| 国产精品亚洲综合色区韩国| 亚洲欧美激情诱惑| 99久久久久国产精品| 久久精品九色| 欧美在线看片| 婷婷精品在线| 中文字幕av一区二区三区四区| 久久中文字幕av| 伊人久久在线| 国产成人在线中文字幕| 久久av网站| 婷婷五月色综合香五月| 国产视频久久| 免费黄色成人| 91精品啪在线观看国产18| 国产不卡精品在线| 久久精品亚洲一区二区| 国产亚洲一区二区三区不卡| 日韩三区四区| 婷婷视频一区二区三区| 亚洲欧洲国产精品一区| 蜜臀av性久久久久蜜臀aⅴ流畅 | 精品欧美激情在线观看| 日韩精品诱惑一区?区三区| 精品国产一区二区三区av片|