<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吧
    值必須被指定到另一個變數才能保存結果  回復  更多評論
      

    主站蜘蛛池模板: 午夜dj免费在线观看| 久久国产精品成人片免费| 成人免费无码精品国产电影| 亚洲精品午夜视频| 亚洲免费观看在线视频| 亚洲国产精品yw在线观看| 成人免费一级毛片在线播放视频| 在线观看亚洲人成网站| 99视频在线精品免费| 亚洲免费视频在线观看| 曰批视频免费40分钟试看天天| 亚洲视频在线不卡| 最新中文字幕免费视频| 久久综合亚洲色hezyo| 亚洲av无码天堂一区二区三区| 一区二区三区精品高清视频免费在线播放 | 日本卡1卡2卡三卡免费| 久久精品国产精品亚洲毛片| 色影音免费色资源| 亚洲精品国产首次亮相| 国产免费无遮挡精品视频| 中国一级毛片免费看视频| 亚洲A∨无码一区二区三区| 四虎1515hh永久久免费| 亚洲成a人无码亚洲成www牛牛| 在线观看免费亚洲| 丁香花在线观看免费观看图片| 久久精品国产亚洲AV高清热| 成年在线网站免费观看无广告 | 亚欧乱色国产精品免费视频| 国产亚洲人成网站在线观看不卡 | 国产午夜精品久久久久免费视| 老色鬼久久亚洲AV综合| 大香人蕉免费视频75| a级毛片免费高清视频| 亚洲精品国产成人99久久| 成年女人午夜毛片免费看| 拍拍拍无挡免费视频网站| 亚洲无人区码一二三码区别图片| 国产亚洲精品影视在线产品| 99久久国产热无码精品免费|