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

您的位置:首頁技術(shù)文章
文章詳情頁

詳解java中BigDecimal精度問題

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

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

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

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

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

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

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

實際控制臺輸出

詳解java中BigDecimal精度問題

為什么會這樣

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

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

浮點數(shù)的值實際上是由一個特定的數(shù)學(xué)公式計算得到的。

二、BigDecimal構(gòu)造函數(shù)1、四種構(gòu)造函數(shù)

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

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

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

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

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的構(gòu)造函數(shù)是會存在精度丟失的可能的。

2、為什么會出現(xiàn)這種情況

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

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

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

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

3、如何解決

有兩種常用的解決辦法。

1、是將double 通過Double.toString(double)先轉(zhuǎn)為String,然后放入BigDecimal的String構(gòu)造函數(shù)中。

2、不通過BigDecimal的構(gòu)造函數(shù),而是通過它的靜態(tài)方法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);}

運行結(jié)果

詳解java中BigDecimal精度問題

這樣也能保證,對與double而言,轉(zhuǎn)BigDecimal不會出現(xiàn)精度丟失的情況。

三、常用方法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余數(shù)=' + remainder_result); System.out.println('4.5和1.5最大數(shù)=' + max_result); System.out.println('4.5和1.5最小數(shù)=' + min_result); System.out.println('-10.5的絕對值=' + abs_result); System.out.println('4.5的相反數(shù)=' + 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余數(shù)=0.0

4.5和1.5最大數(shù)=4.5

4.5和1.5最小數(shù)=1.5

-10.5的絕對值=10.5

4.5的相反數(shù)=-4.5

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

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

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

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

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

這里舉幾個常用的取舍規(guī)則

public static void main(String[] args) { BigDecimal a = new BigDecimal('1.15'); BigDecimal b = new BigDecimal('1'); //不管保留數(shù)字后面是大是小(0除外)都會進1 所以這里輸出為1.2 BigDecimal divide_1 = a.divide(b,1,BigDecimal.ROUND_UP); //保留設(shè)置數(shù)字,后面所有直接去除 所以這里輸出為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'); //那么這里就符合六入了 所以輸出變?yōu)?.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);}

運行結(jié)果

divide_1 = 1.2

divide_2 = 1.1

divide_3 = 1.2

divide_4 = 1.1

divide_5 = 1.2

四、格式化

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

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

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

示例

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

運行結(jié)果

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

這里有幾點在說明下

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

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

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

以上就是詳解java中BigDecimal精度問題的詳細內(nèi)容,更多關(guān)于java的資料請關(guān)注好吧啦網(wǎng)其它相關(guān)文章!

標簽: Java
相關(guān)文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
精品视频自拍| 日韩精品一二三| 免费在线观看成人| 亚洲激情国产| 日韩中文字幕麻豆| 亚洲精品大片| 国产乱码精品一区二区三区四区| 久久精品 人人爱| 欧美国产三级| 国产精品色在线网站| 免费亚洲婷婷| 免费高潮视频95在线观看网站| 久久只有精品| 亚洲精品大全| 国产调教一区二区三区| 麻豆视频一区二区| 久久三级视频| 亚洲三级网址| 精品一区二区三区的国产在线观看| 大香伊人久久精品一区二区| 亚洲午夜av| 亚洲欧美日本国产| 国产在线日韩精品| 亚洲一区二区三区久久久| 久久影视三级福利片| 亚洲高清久久| 国产美女精品视频免费播放软件| 国产在线观看www| jiujiure精品视频播放| 日韩av网站在线免费观看| 日韩精品午夜| 国产日韩免费| 免费国产自线拍一欧美视频| 欧美日韩18| 久久激情中文| 欧美黄色一区| 日韩有码av| 红桃视频国产精品| 中国字幕a在线看韩国电影| 影音先锋久久精品| 国产精品久久久久av电视剧| 亚洲精品一级| 黄色精品网站| 成人在线丰满少妇av| 日韩专区视频网站| 好吊日精品视频| 精品三级av| 国产精品主播在线观看| 天堂va在线高清一区| 免费在线视频一区| 午夜欧美理论片| 99久久夜色精品国产亚洲1000部 | 老牛国产精品一区的观看方式| 高清av不卡| 国产成人精选| 国产91欧美| 乱一区二区av| 日本视频在线一区| 日本午夜精品一区二区三区电影| 在线亚洲一区| 香蕉视频成人在线观看| 不卡视频在线| 激情欧美国产欧美| 亚洲午夜电影| 亚洲一区免费| 亚洲欧美一级| 国产日产一区| 国产亚洲人成a在线v网站| 日本少妇精品亚洲第一区| 国产精品伊人| 精品九九在线| 欧美99久久| 性欧美videohd高精| 99热精品久久| 久久亚洲电影| 国产精品v日韩精品v欧美精品网站| 国产欧美一区二区三区精品观看| 国产精品一区毛片| 丁香婷婷久久| 日韩一级网站| 国产精品三p一区二区| 久久精品福利| 国产一区日韩一区| 鲁大师影院一区二区三区| 亚洲精品在线国产| 国产一区二区三区四区五区传媒| 欧美韩日一区| 不卡一二三区| 婷婷视频一区二区三区| 欧美黄色一区二区| 亚洲特级毛片| 蜜桃91丨九色丨蝌蚪91桃色| 日韩av中文字幕一区| 丁香婷婷久久| 三级欧美在线一区| 国产激情一区| 在线一区视频| 国产一区丝袜| 亚洲乱码久久| 欧美日韩一二三四| 国产欧美丝祙| 中文日韩欧美| 久久av偷拍| 欧美综合二区| 91精品国产自产在线观看永久∴ | 99精品视频在线观看免费播放| 在线亚洲成人| 国产va免费精品观看精品视频| 欧美日韩国产探花| 国产欧美视频在线| 激情综合自拍| 精品国产乱码久久久| 水野朝阳av一区二区三区| 精品九九久久| 日韩av在线免费观看不卡| 日韩综合在线| 亚洲精品高潮| 亚洲一区二区网站| 国产a亚洲精品| 欧美私人啪啪vps| 久久亚洲不卡| 欧美日韩免费观看一区=区三区 | 韩日一区二区| 久久精品超碰| 日韩欧美在线精品| 玖玖精品视频| 久久av在线| 在线看片不卡| 日韩免费av| 色综合五月天| 日韩毛片视频| 日韩精品第一区| 日韩成人精品一区二区| 久久久久久色 | 亚洲手机在线| 婷婷精品视频| 999视频精品| 欧美日韩精品免费观看视欧美高清免费大片 | 日本视频在线一区| 亚洲ab电影| 欧美日韩91| 国产精品欧美日韩一区| 久久成人福利| 麻豆国产在线| 99热国内精品| 老牛影视一区二区三区| 日韩中文字幕在线一区| 国产精品视频3p| av中文字幕在线观看第一页 | 91成人精品在线| 国产美女视频一区二区| 精品一区二区三区中文字幕 | 国产精品色在线网站| 国产+成+人+亚洲欧洲在线| 夜鲁夜鲁夜鲁视频在线播放| 久久精品欧美一区| 免费观看在线色综合| 日韩欧美中文字幕一区二区三区| 国产日产精品_国产精品毛片| 麻豆一区在线| 国精品一区二区| 欧美日韩99| 福利视频一区| 免费在线观看视频一区| 国产精品一线天粉嫩av| 日韩不卡免费高清视频| 在线精品国产亚洲| 国产aⅴ精品一区二区三区久久| 婷婷综合社区| 麻豆精品少妇| 蜜桃传媒麻豆第一区在线观看| 麻豆精品视频在线观看视频| 国产午夜久久| 麻豆理论在线观看| 影音国产精品| 蜜臀av一区二区三区| 国产精品国产三级国产在线观看| 久久男女视频| 国产精品99久久免费| 日精品一区二区三区| 激情五月色综合国产精品| 国产欧美在线观看免费| 日韩一级不卡| 成人福利视频| 欧美精品中文字幕亚洲专区| 桃色一区二区| 日韩高清欧美| 久久伊人亚洲| 欧美亚洲三级| 日韩久久一区| 亚洲1区在线| 亚洲专区一区| 丝袜美腿一区| 国内精品麻豆美女在线播放视频| 日韩二区三区在线观看| 久久国产精品久久w女人spa| 亚洲午夜天堂| 日韩在线看片| 国产美女高潮在线| 国产欧洲在线|