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

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

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

    Atea - Hero's Grave

    面向?qū)ο螅_源,框架,敏捷,云計算,NoSQL,商業(yè)智能,編程思想。

      BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
      40 隨筆 :: 0 文章 :: 28 評論 :: 0 Trackbacks
    首先來預熱一下
    System.out.println(2.00 - 1.10);
    System.out.println(2.00d - 1.10d);
    System.out.println(2.00D - 1.10D);

    答案
    // 0.8999999999999999
    // 0.8999999999999999
    // 0.8999999999999999
    PS:JAVA Puzzlers(Puzzle 2)

    那么,問題是:
    一個浮點數(shù)X,存到DB里是305.35,頁面顯示305.34
    X = ?

    DB用的是MySQL,字段類型是FLOAT(8,2)
    后臺框架用的是Hibernate
    前臺顯示用的是JSTL tag

    答案
    X = 305.345

    原因
    首先把305.345用Hibernate存入DB,DB的保存值會四舍五入為305.35(附錄1),而這時POJO里的值仍為305.345
    而Java的Format默認規(guī)則是"4舍6入5奇偶"(附錄2、附錄3),所以顯示為了305.34

    解決辦法
    1、可以持久化后再從DB取一次值,然后再顯示,可保證DB和頁面的值保持一致
    2、可以多設一位小數(shù)保留位,設為3。然后只用前2位
    3(推薦)、不要用Float或Double,而用Decimal(Java、MySQL皆如此)

    PS:
    那這個問題又和預熱的題目有什么關(guān)系呢?
    浮點數(shù)的數(shù)值是不確定的,遇到了這個問題后,我首先就想到了".99999"這種情況。
    附錄是我親自測試的樣例,在測試過程中發(fā)現(xiàn)了不同版本MySQL在存儲浮點數(shù)上處理不一致(附錄1)。除去".99999"這種情況(限于本人能力有限就不深入研究下去了),可以確定MySQL用的是四舍五入,Java用的是4舍6入5奇偶。

    附錄1 - 不同版本MySQL在存儲浮點數(shù)上的區(qū)別
    MySQL 5.0.27
    FLOAT(
    8,2)

    305.345 -> 305.35
    1305.345 -> 1305.35

    305.34499999999997 -> 305.35
    1305.34499999999997 -> 1305.35

    -----------------------------------
    MySQL 
    5.1.32
    FLOAT(
    8,2)

    305.345 -> 305.35
    1305.345 -> 1305.35

    305.34499999999997 -> 305.34
    1305.34499999999997 -> 1305.35

    -----------------------------------
    MySQL 
    5.1.37
    FLOAT(
    8,2)

    305.345 -> 305.35
    1305.345 -> 1305.35

    305.34499999999997 -> 305.34
    1305.34499999999997 -> 1305.35

    -----------------------------------
    PS:
    使用浮點數(shù)可能會遇到意想不到的問題,因為在MySQL中的所有計算用雙精度完成。
    http://dev.mysql.com/doc/refman/5.1/zh/problems.html#problems-with-float

    附錄2 - JSTL tag的Format
    <!-- 56 -->
    <fmt:formatNumber value="${56.5}" pattern="#,###,###,###"/><br>

    <!-- 305.34 -->
    <fmt:formatNumber value="${305.344}" pattern="###,##0.00"/><br>
    <!-- 305.35 -->
    <fmt:formatNumber value="${305.354}" pattern="###,##0.00"/><br>
    <!-- 1,305.34 -->
    <fmt:formatNumber value="${1305.344}" pattern="###,##0.00"/><br>
    <!-- 1,305.35 -->
    <fmt:formatNumber value="${1305.354}" pattern="###,##0.00"/><br>

    <!-- 305.34 -->
    <fmt:formatNumber value="${305.345}" pattern="###,##0.00"/><br>
    <!-- 1,305.34 -->
    <fmt:formatNumber value="${1305.345}" pattern="###,##0.00"/><br>

    <!-- 305.36 -->
    <fmt:formatNumber value="${305.355}" pattern="###,##0.00"/><br>
    <!-- 305.36 -->
    <fmt:formatNumber value="${305.365}" pattern="###,##0.00"/><br>

    <!-- 305.34 -->
    <fmt:formatNumber value="${305.34499999999997}" pattern="###,##0.00"/><br>
    <!-- 305.35 -->
    <fmt:formatNumber value="${305.35499999999997}" pattern="###,##0.00"/><br>
    <!-- 1,305.34 -->
    <fmt:formatNumber value="${1305.34499999999997}" pattern="###,##0.00"/><br>
    <!-- 1,305.36 -->
    <fmt:formatNumber value="${1305.35499999999997}" pattern="###,##0.00"/><br>

    附錄3 - Java的Format
        @Test
        
    public void formatTest() {

            System.out.println(showFloat(
    305.344));                                 // 305.34
            System.out.println(showFloat(305.354));                                 // 305.35
            System.out.println(showFloat(1305.344));                                // 1,305.34
            System.out.println(showFloat(1305.354));                                // 1,305.35

            System.out.println(showFloat(
    305.345));                                 // 305.34
            System.out.println(showFloat(1305.345));                                // 1,305.34

            System.out.println(showFloat(
    305.355));                                 // 305.36
            System.out.println(showFloat(305.365));                                 // 305.36

            BigDecimal decimal 
    = new BigDecimal("305.345");
            System.out.println(decimal.setScale(
    2, BigDecimal.ROUND_HALF_UP));      // 305.35(四舍五入)

            System.out.println(showFloat(
    305.34499999999997));                      // 305.34
            System.out.println(showFloat(305.35499999999997));                      // 305.35
            System.out.println(showFloat(1305.34499999999997));                     // 1,305.34
            System.out.println(showFloat(1305.35499999999997));                     // 1,305.36

        }

        
    private String showFloat(double d) {
            
    return new DecimalFormat("###,###,###,##0.00").format(d);
        }

    posted on 2010-01-18 12:58 Atea 閱讀(1707) 評論(0)  編輯  收藏 所屬分類: Java languageDatabase
    主站蜘蛛池模板: 亚洲成a人片在线观看中文动漫| 久久久精品免费视频| 免费国产作爱视频网站| 久久久亚洲欧洲日产国码二区| 久久免费线看线看| 久久综合九九亚洲一区| 一级毛片在线观看免费| 亚洲精品中文字幕无码AV| 免费A级毛片无码视频| 亚洲精品一卡2卡3卡三卡四卡| 114级毛片免费观看| 亚洲不卡1卡2卡三卡2021麻豆| 日韩免费一区二区三区在线播放| 亚洲人成日本在线观看| 性色av免费观看| 美女视频黄频a免费大全视频| 亚洲精品国产福利一二区| 国产99久久久国产精免费| 亚洲成AV人片在线播放无码| 久久99精品视免费看| 亚洲av无码一区二区三区观看| 午夜毛片不卡免费观看视频| 免费人成视频在线观看免费| 久久亚洲精品中文字幕三区| **一级毛片免费完整视| 亚洲欧美中文日韩视频| 亚洲av无码不卡私人影院| 免费的全黄一级录像带| 亚洲精品免费网站| 亚洲国产成人精品久久久国产成人一区二区三区综| 深夜福利在线视频免费| 亚洲国产二区三区久久| 成人无码区免费视频观看| 国产91成人精品亚洲精品| 国产A在亚洲线播放| 最近中文字幕mv免费高清视频7| 立即播放免费毛片一级| 亚洲一卡2卡三卡4卡有限公司| 成年丰满熟妇午夜免费视频| 国产精品小视频免费无限app| 亚洲人成在线影院|