• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            Jiang's C++ Space

            創(chuàng)作,也是一種學(xué)習(xí)的過程。

               :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
            弄C++很多年了,沒想到還居然被這種問題所困,其實(shí)不光我了,問了幾個(gè)同道中人,都未能很好解釋為什么,不過我還是記錄一下,有知情人士看到的話不妨留言告知。

            代碼是hello world級(jí)別的,很簡單:
            int _tmain(int argc, _TCHAR* argv[])
            {
                
            int ni = 50;
                unsigned 
            int ui = 100;
                
                printf(
            "%d\n", ni-ui);
                printf(
            "%d\n", (ni-ui)*2);
                printf(
            "%d\n", (ni-ui)/2);
                printf(
            "%d\n", (ni-(int)ui)/2);
                
            return 0;
            }
            問題:輸出結(jié)果是什么?
            我預(yù)期的輸出結(jié)果應(yīng)該是這樣:
            -50
            -100
            -25
            -25
            而事實(shí)上是:
            -50
            -100
            2147483623
            -25
            在VC6,VS2005和VS2008上調(diào)試過,結(jié)果完全一致,這就表示,(ni-ui)/2的結(jié)果被認(rèn)為是一個(gè)無符號(hào)整型,為什么會(huì)這樣呢?我看了一下反匯編……其實(shí),我沒看明白。(匯編沒學(xué)好)

            這種小問題可能會(huì)引發(fā)大問題,我最近在設(shè)計(jì)一個(gè)程序,把圖片貼到窗口上,圖片的寬和高被我設(shè)計(jì)為無符號(hào)的,因?yàn)閷捄透咦钚?,不可能是負(fù)數(shù),而圖片的繪制位置則有可能是負(fù)數(shù),這跟坐標(biāo)系有關(guān),這樣有符號(hào)和無符號(hào)之間就有可能出現(xiàn)了上面的那種操作,導(dǎo)致程序出現(xiàn)了一些怪異的行為,通過調(diào)試,發(fā)現(xiàn)是這個(gè)問題。

            解決方法很簡單,只要加上一個(gè)強(qiáng)制轉(zhuǎn)換即可,像代碼最后一個(gè)printf語句那樣。但為什么這樣我就不太清楚了,是C++的規(guī)范,還是編譯器的問題,有其它編譯器的朋友可以試試看。
            posted on 2010-06-12 10:43 Jiang Guogang 閱讀(2036) 評(píng)論(7)  編輯 收藏 引用 所屬分類: Knowledge

            評(píng)論

            # re: 怪異的有符號(hào)/無符號(hào)轉(zhuǎn)換問題 2010-06-12 10:46 mr.huang
            太詭異。。。麻煩了。。。我們的工程都很少注意這些。  回復(fù)  更多評(píng)論
              

            # re: 怪異的有符號(hào)/無符號(hào)轉(zhuǎn)換問題 2010-06-12 17:45 OwnWaterloo
            printf("%d %u\n", ni-ui, ni-ui);
            printf("%d %u\n", (ni-ui)*2, (ni-ui)*2);
            printf("%d %u\n", (ni-ui)/2, (ni-ui)/2);
            printf("%d %u\n", (ni-(int)ui)/2, (ni-(int)ui)/2);

            觀察輸出結(jié)果, 明白了嗎?  回復(fù)  更多評(píng)論
              

            # re: 怪異的有符號(hào)/無符號(hào)轉(zhuǎn)換問題 2010-06-13 10:07 博主
            @OwnWaterloo
            我的問題如文中所說,“是C++的規(guī)范,還是編譯器的問題”,(ni-ui)*2被認(rèn)為是一個(gè)有符號(hào)的整型,而為什么(ni-ui)/2卻被認(rèn)為是一個(gè)無符號(hào)整型,是C++的規(guī)范,還是編譯器的問題?  回復(fù)  更多評(píng)論
              

            # re: 怪異的有符號(hào)/無符號(hào)轉(zhuǎn)換問題 2010-06-13 10:36 OwnWaterloo
            @博主
            規(guī)范。

            二元操作符始終會(huì)將操作數(shù)轉(zhuǎn)換為同一類型計(jì)算。

            轉(zhuǎn)換規(guī)則很復(fù)雜, 但有2點(diǎn):

            1. signed T的rank一定比unsigned T要低
            2. int 剛好超過默認(rèn)參數(shù)提升的范圍

            所以 int op unsigned 一定是都轉(zhuǎn)換為unsignd計(jì)算。
              回復(fù)  更多評(píng)論
              

            # re: 怪異的有符號(hào)/無符號(hào)轉(zhuǎn)換問題 2010-06-20 21:33 gejun
            “(ni-ui)*2被認(rèn)為是一個(gè)有符號(hào)的整型,而為什么(ni-

            ui)/2卻被認(rèn)為是一個(gè)無符號(hào)整型,是C++的規(guī)范,還是編

            譯器的問題?”

            hi,Jiang. 又在默默耕耘啦~~

            請問你根據(jù)什么知道(ni-ui)*2被認(rèn)為是一個(gè)有符號(hào)的整

            型而(ni-ui)/2卻被認(rèn)為是一個(gè)無符號(hào)整型?

            如果你是根據(jù)printf("%d",XXX)的輸出,那就錯(cuò)了。因?yàn)?br>
            printf("%d",XXX)不管XXX是什么類型都會(huì)把XXX當(dāng)做有符

            號(hào)數(shù)輸出的。

            我做了個(gè)實(shí)驗(yàn)證明之前那位網(wǎng)友所說,int op unsigned

            一定是都轉(zhuǎn)換為unsignd,是對(duì)的。

            (寫了段代碼來證明那位網(wǎng)友的結(jié)論:
            unsigned int ui = 1;
            int ni = 2;

            if((ui - ni)<0){
            //如果(ui - ni)被轉(zhuǎn)換為有符號(hào)數(shù)就會(huì)進(jìn)入這

            個(gè)分支
            printf("should not see me.\n\r");
            })

            回到你說的問題。那輸出結(jié)果到底是什么?

            把你代碼中的%d換成%x就真相大白了。

            printf("%x\n", ni-ui);
            printf("%x\n", (ni-ui)*2);
            printf("%x\n", (ni-ui)/2);
            printf("%x\n", (ni-(int)ui)/2);

            輸出結(jié)果如下:
            ffffffce
            ffffff9c
            7fffffe7
            ffffffe7

            那對(duì)于你說有問題的那兩句話,
            (ni-ui)/2輸出為7fffffe7
            (ni-(int)ui)/2)輸出為ffffffe7
            為什么會(huì)有這個(gè)差異?
            請看看匯編代碼。

            在計(jì)算(ni-ui)/2時(shí),編譯器使用shr來計(jì)算結(jié)果。shr是

            邏輯右移,右移的同時(shí)高位填0,所以得到7fffffe7。
            在計(jì)算(ni-(int)ui)/2時(shí),編譯器使用sar來計(jì)算結(jié)果。

            sar是算術(shù)右移,右移的同時(shí)保留符號(hào)位,所以得到

            ffffffe7。

            那為什么(ni-ui)/2采用shr而(ni-(int)ui)/2采用sar?
            我想就像前面那位網(wǎng)友說的,(ni-ui)被轉(zhuǎn)換為無符號(hào)數(shù)

            ,所以編譯器采用shr忽略符號(hào)位;而(ni-(int)ui)被強(qiáng)

            制轉(zhuǎn)換為有符號(hào)數(shù),所以編譯器采用了sar以考慮符號(hào)位


              回復(fù)  更多評(píng)論
              

            # re: 怪異的有符號(hào)/無符號(hào)轉(zhuǎn)換問題 2010-06-21 08:29 pmerofc
            (ni-ui)*2被認(rèn)為是一個(gè)有符號(hào)的整型,而為什么(ni-ui)/2卻被認(rèn)為是一個(gè)無符號(hào)整型

            (ni-ui)*2 , (ni-ui)/2 都是 unsigned

            原因就是OwnWaterloo說的類型轉(zhuǎn)換

            至于輸出-100,那完全是%d的緣故  回復(fù)  更多評(píng)論
              

            # re: 怪異的有符號(hào)/無符號(hào)轉(zhuǎn)換問題 2010-06-21 15:58 博主
            Thank you all.
            我已經(jīng)了解。總結(jié)回來就是:有符號(hào)和無符號(hào)的運(yùn)算,必須要小心謹(jǐn)慎一些。  回復(fù)  更多評(píng)論
              

            亚洲午夜精品久久久久久人妖| 91秦先生久久久久久久| 色婷婷噜噜久久国产精品12p| 老司机午夜网站国内精品久久久久久久久| 国内精品久久久久久麻豆| 久久综合精品国产一区二区三区| 亚洲国产精品一区二区三区久久| 人妻少妇久久中文字幕| 久久99国产精品久久| 欧美成人免费观看久久| 久久精品蜜芽亚洲国产AV| 久久婷婷五月综合成人D啪| 欧美大香线蕉线伊人久久| 久久国产成人午夜aⅴ影院| 亚洲va久久久噜噜噜久久男同| 99久久这里只有精品| 久久99热这里只频精品6| 国产亚洲色婷婷久久99精品91| 久久亚洲精品成人av无码网站| 久久久久噜噜噜亚洲熟女综合| 久久av无码专区亚洲av桃花岛| 久久久国产精华液| 四虎国产精品免费久久5151| 国产成人精品综合久久久| 国产ww久久久久久久久久| 久久精品人成免费| 久久精品国产亚洲AV无码偷窥| 久久午夜无码鲁丝片秋霞| 久久97久久97精品免视看秋霞| 久久婷婷五月综合97色一本一本| 伊人久久亚洲综合影院| 久久午夜无码鲁丝片午夜精品| 亚洲国产天堂久久综合网站| 久久久女人与动物群交毛片| 一本色道久久HEZYO无码| 久久成人小视频| 久久国产亚洲精品| 亚洲午夜久久久久久久久电影网 | 久久精品一区二区影院| 色综合久久综合网观看| 91精品国产91久久久久久|