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

            創作,也是一種學習的過程。

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

            代碼是hello world級別的,很簡單:
            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;
            }
            問題:輸出結果是什么?
            我預期的輸出結果應該是這樣:
            -50
            -100
            -25
            -25
            而事實上是:
            -50
            -100
            2147483623
            -25
            在VC6,VS2005和VS2008上調試過,結果完全一致,這就表示,(ni-ui)/2的結果被認為是一個無符號整型,為什么會這樣呢?我看了一下反匯編……其實,我沒看明白。(匯編沒學好)

            這種小問題可能會引發大問題,我最近在設計一個程序,把圖片貼到窗口上,圖片的寬和高被我設計為無符號的,因為寬和高最小為0,不可能是負數,而圖片的繪制位置則有可能是負數,這跟坐標系有關,這樣有符號和無符號之間就有可能出現了上面的那種操作,導致程序出現了一些怪異的行為,通過調試,發現是這個問題。

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

            評論

            # re: 怪異的有符號/無符號轉換問題 2010-06-12 10:46 mr.huang
            太詭異。。。麻煩了。。。我們的工程都很少注意這些。  回復  更多評論
              

            # re: 怪異的有符號/無符號轉換問題 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);

            觀察輸出結果, 明白了嗎?  回復  更多評論
              

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

            # re: 怪異的有符號/無符號轉換問題 2010-06-13 10:36 OwnWaterloo
            @博主
            規范。

            二元操作符始終會將操作數轉換為同一類型計算。

            轉換規則很復雜, 但有2點:

            1. signed T的rank一定比unsigned T要低
            2. int 剛好超過默認參數提升的范圍

            所以 int op unsigned 一定是都轉換為unsignd計算。
              回復  更多評論
              

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

            ui)/2卻被認為是一個無符號整型,是C++的規范,還是編

            譯器的問題?”

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

            請問你根據什么知道(ni-ui)*2被認為是一個有符號的整

            型而(ni-ui)/2卻被認為是一個無符號整型?

            如果你是根據printf("%d",XXX)的輸出,那就錯了。因為

            printf("%d",XXX)不管XXX是什么類型都會把XXX當做有符

            號數輸出的。

            我做了個實驗證明之前那位網友所說,int op unsigned

            一定是都轉換為unsignd,是對的。

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

            if((ui - ni)<0){
            //如果(ui - ni)被轉換為有符號數就會進入這

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

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

            把你代碼中的%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);

            輸出結果如下:
            ffffffce
            ffffff9c
            7fffffe7
            ffffffe7

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

            在計算(ni-ui)/2時,編譯器使用shr來計算結果。shr是

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

            sar是算術右移,右移的同時保留符號位,所以得到

            ffffffe7。

            那為什么(ni-ui)/2采用shr而(ni-(int)ui)/2采用sar?
            我想就像前面那位網友說的,(ni-ui)被轉換為無符號數

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

            制轉換為有符號數,所以編譯器采用了sar以考慮符號位


              回復  更多評論
              

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

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

            原因就是OwnWaterloo說的類型轉換

            至于輸出-100,那完全是%d的緣故  回復  更多評論
              

            # re: 怪異的有符號/無符號轉換問題 2010-06-21 15:58 博主
            Thank you all.
            我已經了解。總結回來就是:有符號和無符號的運算,必須要小心謹慎一些。  回復  更多評論
              

            国产精品乱码久久久久久软件| 久久亚洲精品无码播放| 久久人人爽人人爽人人片AV不| 亚洲狠狠综合久久| 久久精品国产一区二区| 久久久久久久综合狠狠综合| 亚洲精品乱码久久久久久按摩| 精品乱码久久久久久久| 久久久久九九精品影院| 久久久噜噜噜久久熟女AA片| 久久精品一区二区国产| 区久久AAA片69亚洲| 999久久久免费国产精品播放| 婷婷国产天堂久久综合五月| 久久国产色AV免费观看| 一本大道久久香蕉成人网| 99久久人妻无码精品系列 | 亚洲AⅤ优女AV综合久久久| 久久无码国产| 久久久亚洲欧洲日产国码二区| 美女写真久久影院| 久久国产高潮流白浆免费观看| 欧美日韩精品久久久久 | 久久综合九色综合精品| 亚洲国产精品无码久久久不卡| 精品视频久久久久| 99久久精品九九亚洲精品| 久久精品亚洲日本波多野结衣| 综合久久给合久久狠狠狠97色| 久久精品成人一区二区三区| 青青国产成人久久91网 | 中文精品99久久国产 | 久久亚洲熟女cc98cm| 久久人人爽人人爽人人片AV麻豆 | 久久久久国产日韩精品网站| 久久精品国产99国产电影网 | 合区精品久久久中文字幕一区| 国产 亚洲 欧美 另类 久久| 日韩欧美亚洲综合久久影院d3| 久久99国产精品久久99果冻传媒 | 成人免费网站久久久|