<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    鷹翔宇空

    學習和生活

    BlogJava 首頁 新隨筆 聯系 聚合 管理
      110 Posts :: 141 Stories :: 315 Comments :: 1 Trackbacks

    這兩天,不斷的有人問我java中數值計算的精度問題,以前在項目中碰到過,吃了不少苦頭,但一直也沒管它,現在先小結一下,以后再慢慢補充吧,否則,過段時間又忘了。
         java
    中的基本類型float有著很嚴重的精度缺失問題,這個我主要是通過java.math.BigDecimal來彌補,但BigDecimal畢竟是一個類,有著對象的創建銷毀等繁瑣的事情,況且java中類本身沒有destroy()方法,這就把一切對象的徹底銷毀后內存的回收,變成了一個不可測的變數,縱使你調用了system.gc(),但此方法的執行時機卻又是未知的;所以這就要求程序員要盡可能少的創建對象(當然這還與java本身的確非常消耗內存有關),當對象一旦不用,盡可能的置為null,否則當程序運行幾次后就會發現內存占有率高居不下,甚至有導致死機可能。BigDecimal還有一點要引起注意的是,兩個對象即使值確實相等,但它們相比較時也可能會引起不等的結果,舉個例子如:

    BigDecimal testA = new BigDecimal(200)BigDecimal testB = new BigDecimal(200.00),也許你認為testA.equals(testB)==true;但結果是false。然而testA.toString().equals(testB.toString())==true,這是因為testB.toString()的值為200,在進行類型轉換時,它已把小數點后的兩個零去掉了。為了解決這個問題,我通常的做法是將它們的小數點位數補起后再進行比較,這樣是肯定不會出錯了,如testA = testA.setScale(2,5);testB = testB.setScale(2,5);當然了你可以根據需要將小數點位數設多或設置少一點,setScaleint,int)中第一位數為設置的小數點位數,第二位是四舍五入的界值,你可以隨意修改,如6,就是大于等于6是就進位。還有testA = testA.setScale(2,5)這種寫法在用BigDecimal時將會一直出現,因為它必須要通過給自身返回值來替代已經存在的值,如果你這樣寫testA.add(new BigDecimal(0)),那你會發現你的結果并不是想象中的200,而是0。當然加減乘除都是一樣的。至于剛才的比較為何不用testA.floatValue(),當然還是因為會造成精度丟失的緣故了,當然如果你的小數位數不超過5位的話,也是可以的,如果是超過5位,那就和第五位的值有關了(因為它僅保留五位小數),顯示如果第五位大于等于五,即使第六位為零,也會在第五位上加一,否則后面的只會被截掉!
      說到這里,忽然想起javascript中的尾數和精度問題,javascript中有一個方法“toFixed(),這個方法就是用來截取小數點后尾數的長度的。例:var a = 343.12345465;var b = b.toFixed(4);這樣b小數點后的尾數就是4位了,注意,它是按照四舍五入進行截取的。

    posted on 2005-12-17 15:30 TrampEagle 閱讀(10505) 評論(9)  編輯  收藏 所屬分類: 學習體會

    Feedback

    # re: java中數值計算的精度問題 2005-12-21 15:58 not_sub
    用 double 類型,一般就夠用了。 float 精度只有 6-7 位有效數字,當然不夠。  回復  更多評論
      

    # re: java中數值計算的精度問題 2006-04-25 09:51 不同意樓上的
    double用來做計算非常的不準確,加減之后都是接近值,但都不是精確值  回復  更多評論
      

    # re: java中數值計算的精度問題 2007-07-15 16:30 fon123
    在從數值上比較兩個 BigDecimal 值時,應該使用 compareTo() 而不是 equals()   回復  更多評論
      

    # re: java中數值計算的精度問題 2007-08-23 15:07 不知道真的假的
    BigDecimal testAdd = new BigDecimal( 200 );
    testAdd.add( new BigDecimal( 0 ) );
    System.out.println( testAdd );

    這是照LZ的說法寫
    不幸的是,輸出是200
    是不是代碼寫錯?  回復  更多評論
      

    # re: java中數值計算的精度問題 2007-09-18 11:01 zhw
    可以用BigDecimal.valueOf()
    這樣不用new新對象的。  回復  更多評論
      

    # re: java中數值計算的精度問題 2007-10-17 20:17 T.WOLF
    @不知道真的假的
    200才是正確答案,我一直就是用add來完成加法操作的  回復  更多評論
      

    # re: java中數值計算的精度問題[未登錄] 2008-10-10 18:48 java菜鳥
    這個帖子的內容不知道什么時候測試的,我用1.5測試和樓主所說有點不一致  回復  更多評論
      

    # re: java中數值計算的精度問題 2008-12-24 10:59 Meison
    BigDecimal.stripTrailingZeros().....  回復  更多評論
      

    # re: java中數值計算的精度問題 2011-09-05 21:05 sanga
    BigDecimal testAdd = new BigDecimal( 200 );
    testAdd.add( new BigDecimal( 1 ) );
    System.out.println( testAdd );
    我想LZ的意思是指輸出的結果依然為200吧
    值必須被指定到另一個變數才能保存結果  回復  更多評論
      

    主站蜘蛛池模板: 国产精品九九久久免费视频| 亚洲视频在线观看视频| 中文字幕亚洲不卡在线亚瑟| 久久夜色精品国产噜噜亚洲AV| 51精品视频免费国产专区| 亚洲av无码专区青青草原| 最近最新高清免费中文字幕| 成年美女黄网站18禁免费| 亚洲卡一卡2卡三卡4卡无卡三| MM1313亚洲国产精品| 中文字幕亚洲一区| 亚洲免费观看网站| 在线91精品亚洲网站精品成人| 18女人水真多免费高清毛片| 亚洲亚洲人成综合网络| 中文字幕无码一区二区免费| 亚洲AV日韩精品久久久久| 一区二区三区在线观看免费| 成人在线视频免费| 亚洲国产精品成人精品无码区在线| 亚洲AV无码AV男人的天堂不卡 | 国产大片免费观看中文字幕| 亚洲AV一宅男色影视| 中文字幕久精品免费视频| 亚洲国产精彩中文乱码AV| 日韩免费电影网站| 亚洲a视频在线观看| 免费羞羞视频网站| 最近免费中文字幕中文高清 | 亚洲AV永久无码精品| 国产无人区码卡二卡三卡免费| 亚洲熟伦熟女专区hd高清| 亚洲国产精品无码久久青草| 中文成人久久久久影院免费观看| 久久夜色精品国产嚕嚕亚洲av| 成年人免费的视频| 一级特黄a免费大片| 亚洲国产亚洲综合在线尤物| 亚洲第一黄色网址| 青青青免费国产在线视频小草| 窝窝影视午夜看片免费|