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

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

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

    隨筆 - 9  文章 - 21  trackbacks - 0
    <2008年5月>
    27282930123
    45678910
    11121314151617
    18192021222324
    25262728293031
    1234567

    常用鏈接

    留言簿(1)

    隨筆分類(9)

    隨筆檔案(9)

    搜索

    •  

    最新評論

    閱讀排行榜

    評論排行榜

    第 2 天的問題

    請考慮下面這段話所描述的問題:

    小明在超市購買了一個價值¥1.10的東西,但是他錢包中只有兩元一張的鈔票。如果他用一張兩元的鈔票支付,那么應(yīng)該找給他多少零錢呢?

    下面是一個試圖解決上述問題的程序,它會打印出什么呢?

    
    public class Change{
        public static void main(String args[]){
            System.out.println(2.00 - 1.10);
        }
    }
    
    

    第 2 天問題的解答

    你可能會說,這不是很簡單嘛!輸出0.90。但實際的輸出確實:0.8999999999999999。

    原因

    一、程序如何才能知道你想要打印小數(shù)點后兩位小數(shù)呢?

    JDK API文檔中關(guān)于Double.toString的部分指出:

    Double.toString的返回值,是足以將double類型的值與最靠近它的臨近值區(qū)分出來的最短的小數(shù),它在小數(shù)點之前和之后都至少有一位。

    因此,看起來,該程序應(yīng)該打印0.9是合理的。

    二、并不是所有的小數(shù)都可以用二進制浮點數(shù)來精確表示的。

    問題在于1.1這個數(shù)字不能被精確表示成為一個double,因此它被表示成為最接近它的double值。 該程序從2中減去的就是這個值。 遺憾的是,這個計算的結(jié)果并不是最接近0.9的double值。 表示結(jié)果的double值的最短表示就是你所看到的打印出來的那個可惡的數(shù)字。

    第 2 天問題的解決辦法

    方法一

    
    //拙劣的解決方案--仍舊是使用二進制浮點數(shù)
    System.out.printf("%.2f%n",2.00 - 1.10);
    

    這條語句打印的是正確的結(jié)果,但是這并不表示它就是對底層問題的通用解決方案。它使用的仍舊是二進制浮點數(shù)的double運算。 浮點運算在一個范圍很廣的值域上提供了很好的近似,但是它通常不能產(chǎn)生精確的結(jié)果。 二進制浮點對于貨幣計算是非常不適合的,因為它不可能將0.1--或者10的其它任何次負冪--精確表示為一個長度有限的二進制小數(shù)

    方法二

    System.out.println((200 - 110) + "分");
    

    這是在Java中一種簡單的解決方法。在Java標準庫中,有一個類似的范例Date類,Date類的對于時間的內(nèi)部表示就是一個以毫秒為單位的long整數(shù)。 對于像貨幣這樣的數(shù)值,可以用int或long來表示。如果你采納了解決方法,請確保該整數(shù)類型大到足夠表示在程序中你將要用到的所有值

    方法三

    
    import java.math.BigDecimal;
    
    public class Change1{
        public static void main(String args[]){
            System.out.println(new BigDecimal("2.00").subtract(new BigDecimal("1.10")));
        }
    }
    
    

    解決該問題的另一種方式是使用執(zhí)行精確小數(shù)運算的BigDecimal。 這里要告誡你一點: 一定要用BigDecimal(String)構(gòu)造器,而千萬不要用BigDecimal(double)。 后一個構(gòu)造器將用它的參數(shù)的"精確"值來創(chuàng)建一個實例:new BigDecimal(1.1)將返回一個表示1.100000000000000055511151231257827021181583404541015625 的BigDecimal。

    這個版本并不是十分地完美,因為Java并沒有為BigDecimal提供任何語言上的支持。原因:

    • 使用BigDecimal的計算很有可能比那些使用原始類型的計算要慢一些,對某些大量使用小數(shù)計算的程序來說,這可能會成為問題,而對大多數(shù)程序來說,這顯得一點也不重要。
    • Java不允許運算符重載。使得代碼不夠直觀。

    總結(jié)

    在需要精確答案的地方,要避免使用float和double。

    對于貨幣計算,要使用int、long或BigDecimal。

    對于語言設(shè)計者來說,應(yīng)該考慮對小數(shù)運算提供語言支持。可以支持下列方式中的一種。

    • 提供對操作符重載的有限支持, 以使得運算符可以被塑造為能夠?qū)?shù)值引用類型起作用, 例如BigDecimal。
    • 提供原始的小數(shù)類型,就像 COBOL 與 PL/I 所作的一樣。

    今天的問題

    被除數(shù)表示的是一天里的微秒數(shù);而除數(shù)表示的是一天里的毫秒數(shù)。這個程序會打印出什么呢?

    
    public class LongDivision{
        public static void main(String args[]){ 
            final long MICROS_PER_DAY = 24 * 60 * 60 * 1000 * 1000; 
            final long MILLIS_PER_DAY = 24 * 60 * 60 * 1000; 
            System.out.println(MICROS_PER_DAY/MILLIS_PER_DAY); 
        } 
    } 
    
    
    posted on 2008-05-16 22:50 李四飛刀 閱讀(1301) 評論(0)  編輯  收藏 所屬分類: 每日一題
    主站蜘蛛池模板: 国产亚洲美女精品久久久| 亚洲欧美在线x视频| 亚洲M码 欧洲S码SSS222| 国产1000部成人免费视频| 国产精品一区二区三区免费| 亚洲欧美日韩综合久久久久| 精品亚洲成AV人在线观看| 亚洲高清最新av网站| 蜜桃精品免费久久久久影院| 18观看免费永久视频| 暖暖在线视频免费视频| 精品国产福利尤物免费| 人成电影网在线观看免费| 色欲aⅴ亚洲情无码AV蜜桃 | 又长又大又粗又硬3p免费视频| 亚洲人成未满十八禁网站| 亚洲性一级理论片在线观看| 久久亚洲国产精品五月天| 亚洲中文字幕无码一区| 亚洲一级特黄大片无码毛片| 日韩亚洲国产综合久久久| 看全色黄大色大片免费久久| 啦啦啦手机完整免费高清观看| 在线观看无码AV网站永久免费| 16女性下面扒开无遮挡免费| 最近最好最新2019中文字幕免费| 日韩电影免费在线观看| 久久久久国产精品免费免费不卡 | 国产亚洲色婷婷久久99精品91| 国产免费人视频在线观看免费| 日本高清免费网站| 国产成人精品免费直播| 国产大片免费观看中文字幕| 国产男女猛烈无遮档免费视频网站 | 香蕉视频在线观看免费国产婷婷| 曰批全过程免费视频在线观看| 91九色精品国产免费| 男女免费观看在线爽爽爽视频| 福利免费观看午夜体检区| 无码国产精品一区二区免费I6| 成人免费无码大片A毛片抽搐|