• <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 閱讀(2024) 評論(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.
            我已經了解。總結回來就是:有符號和無符號的運算,必須要小心謹慎一些。  回復  更多評論
              

            久久综合88熟人妻| 精品久久久一二三区| 国产成人精品白浆久久69| 国产亚洲精久久久久久无码| 久久综合久久综合久久综合| 久久狠狠一本精品综合网| 久久久久久久久久久| 午夜久久久久久禁播电影| 久久久91精品国产一区二区三区| 久久精品国产福利国产琪琪| 无码精品久久久久久人妻中字| AAA级久久久精品无码区| 久久伊人五月丁香狠狠色| 久久97久久97精品免视看秋霞| 99精品国产综合久久久久五月天| 久久久久夜夜夜精品国产| 亚洲中文字幕久久精品无码喷水 | 久久午夜福利电影| 久久夜色精品国产噜噜麻豆| 久久青青草原精品国产不卡| 人妻精品久久久久中文字幕69 | 国产99久久久国产精品~~牛| 久久精品国产2020| 亚洲国产成人久久精品99| 久久国产视屏| 久久精品国产亚洲Aⅴ香蕉 | 午夜不卡888久久| 久久精品国产亚洲av高清漫画 | 久久久精品人妻一区二区三区蜜桃 | 四虎久久影院| 国产69精品久久久久99| 国产精品一区二区久久| 99麻豆久久久国产精品免费| 久久午夜伦鲁片免费无码| 久久久久亚洲AV无码观看| 久久人人爽人人爽人人爽| 亚洲精品NV久久久久久久久久| 久久综合五月丁香久久激情| 久久久久亚洲AV成人网| 久久久无码精品亚洲日韩软件| 久久久久国产视频电影|