<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)

    搜索

    •  

    最新評(píng)論

    閱讀排行榜

    評(píng)論排行榜

    第 5 天的問(wèn)題

    下面的程序是對(duì)兩個(gè)十六進(jìn)制(hex)字面常量進(jìn)行相加,然后打印出十六進(jìn)制的結(jié)果。這個(gè)程序會(huì)打印出什么呢?

    public class JoyOfHex {
        public static void main(String[] args) {
            System.out.println(Long.toHexString(0x100000000L + 0xcafebabe));
        }
    }
    

    第 5 天問(wèn)題的解答

    看起來(lái)很明顯,該程序應(yīng)該打印出1cafebabe。畢竟,這確實(shí)就是十六進(jìn)制數(shù)字10000000016與cafebabe16的和。該程序使用的是long型運(yùn)算,它可以支持16位十六進(jìn)制數(shù),因此運(yùn)算溢出是不可能的。

    遺憾的告訴你,結(jié)果是cafebabe,并沒(méi)有任何前導(dǎo)的1。這個(gè)輸出表示的是正確結(jié)果的低32位,但是不知何故,第33位丟失了。

    原因

    十進(jìn)制字面常量具有一個(gè)很好的屬性,即所有的十進(jìn)制字面常量都是正的,而十六進(jìn)制或是八進(jìn)制字面常量并不具備這個(gè)屬性。

    要想書(shū)寫(xiě)一個(gè)負(fù)的十進(jìn)制常量,可以使用一元取反操作符(-)連接一個(gè)十進(jìn)制字面常量。以這種方式,你可以用十進(jìn)制來(lái)書(shū)寫(xiě)任何int或long型的數(shù)值,不管它是正的還是負(fù)的,并且負(fù)的十進(jìn)制常數(shù)可以很明確地用一個(gè)減號(hào)符號(hào)來(lái)標(biāo)識(shí)。

    但是十六進(jìn)制和八進(jìn)制字面常量并不是這么回事,它們可以具有正的以及負(fù)的數(shù)值。如果十六進(jìn)制和八進(jìn)制字面常量的最高位被置位了,那么它們就是負(fù)數(shù)。在這個(gè)程序中,數(shù)字0xcafebabe是一個(gè)int常量,它的最高位被置位了,所以它是一個(gè)負(fù)數(shù)。它等于十進(jìn)制數(shù)值-889275714。

    該程序執(zhí)行的這個(gè)加法是一種"混合類型的計(jì)算(mixed-type computation)。左操作數(shù)是 long 類型的,而右操作數(shù)是 int 類型的。為了執(zhí)行該計(jì)算,Java將int類型的數(shù)值用拓寬原始類型轉(zhuǎn)換提升為一個(gè)long類型,然后對(duì)兩個(gè)long類型數(shù)值相加。因?yàn)閕nt是一個(gè)有符號(hào)的整數(shù)類型,所以這個(gè)轉(zhuǎn)換執(zhí)行的是符合擴(kuò)展,它將負(fù)的int類型的數(shù)值提升為一個(gè)在數(shù)值上相等的long類型數(shù)值。

    解決辦法

    System.out.println(Long.toHexString(0x100000000L + 0xcafebabeL));
    

    這個(gè)加法的右操作數(shù)0xcafebabe被提升為了long類型的數(shù)值0xffffffffcafebabeL。這個(gè)數(shù)值之后被加到了左操作數(shù)0x100000000L上。當(dāng)作為int類型來(lái)被審視時(shí),經(jīng)過(guò)符號(hào)擴(kuò)展之后的右操作數(shù)的高32位是-1,而左操作數(shù)的高32位是1,將這兩個(gè)數(shù)值相加就得到了0,這也就解釋了為什么在程序輸出中前導(dǎo)1丟失了。

    第 5 天問(wèn)題的總結(jié)

    這個(gè)題給我們的教訓(xùn)是:混合類型的計(jì)算可能會(huì)產(chǎn)生混淆,尤其是十六進(jìn)制和八進(jìn)制字面常量無(wú)需顯式的減號(hào)符號(hào)就可以表示負(fù)的數(shù)值。為了避免這種窘境,通常最好是避免混合類型的計(jì)算

    對(duì)于語(yǔ)言的設(shè)計(jì)者們來(lái)說(shuō),應(yīng)該考慮支持無(wú)符號(hào)的整數(shù)類型,從而根除符號(hào)擴(kuò)展的可能性??赡軙?huì)有這樣的爭(zhēng)辯:負(fù)的十六進(jìn)制和八進(jìn)制字面常量應(yīng)該被禁用,但是這可能會(huì)挫傷程序員,他們經(jīng)常使用十六進(jìn)制字面常量來(lái)表示那些符號(hào)沒(méi)有任何重要含義的數(shù)值。


    今天的問(wèn)題

    轉(zhuǎn)型被用來(lái)將一個(gè)數(shù)值從一種類型轉(zhuǎn)換到另一種類型。下面的程序連續(xù)使用了三個(gè)轉(zhuǎn)型。那么它到底會(huì)打印出什么呢?

    public class Multicast {
        public static void main(String[] args) {
            System.out.println((int) (char) (byte) -1);
        }
    }
    
    
    posted on 2008-05-17 17:52 李四飛刀 閱讀(1579) 評(píng)論(2)  編輯  收藏 所屬分類: 每日一題

    FeedBack:
    # re: 第 6 天: 解答 -- 16進(jìn)制的趣事, 問(wèn)題 -- 轉(zhuǎn)型 2008-05-19 12:55 草兒
    你是不是建議我們都去買一本 《Java 解惑》?   回復(fù)  更多評(píng)論
      
    # re: 第 6 天: 解答 -- 16進(jìn)制的趣事, 問(wèn)題 -- 轉(zhuǎn)型 2008-05-21 16:29 d
    很無(wú)聊!?。。。。。?,如果你寫(xiě)過(guò)c++,你說(shuō)的都是入門(mén)基礎(chǔ)!  回復(fù)  更多評(píng)論
      
    主站蜘蛛池模板: 在线A级毛片无码免费真人| 成人免费观看一区二区| 免费在线黄色网址| 亚洲AV无码一区二区乱子仑| 在线观看日本亚洲一区| 成人在线免费看片| 亚洲va久久久久| 在线a毛片免费视频观看| 久久精品亚洲日本波多野结衣| 99免费精品视频| 亚洲午夜久久久久久久久久| 国产无遮挡又黄又爽免费网站| 毛片免费观看的视频| 亚洲色少妇熟女11p| 四虎免费久久影院| 久久精品成人免费国产片小草| 成人午夜性A级毛片免费| 亚洲精品无码不卡在线播放| 四虎影视在线影院在线观看免费视频| 夜夜春亚洲嫩草影院| 97se亚洲国产综合自在线| 一个人免费高清在线观看| 毛片亚洲AV无码精品国产午夜| 国产成人yy免费视频| 亚洲av日韩综合一区久热| 亚洲综合精品网站在线观看| 鲁丝片一区二区三区免费 | 91精品视频免费| 无码亚洲成a人在线观看| 久久精品国产亚洲一区二区三区| 豆国产96在线|亚洲| 国外亚洲成AV人片在线观看| 日韩大片免费观看视频播放| 亚洲乱码国产一区三区| 青青草97国产精品免费观看| 亚洲AV永久无码区成人网站| 欧美日韩国产免费一区二区三区| 亚洲女人影院想要爱| 日韩a在线观看免费观看| 国产猛男猛女超爽免费视频| 亚洲一卡2卡三卡4卡无卡下载|