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

            亚洲AV无码久久寂寞少妇| 91精品国产乱码久久久久久 | 久久精品国产福利国产秒| 人人狠狠综合久久亚洲88| 日韩电影久久久被窝网| 日韩精品无码久久久久久| 久久久久久久综合日本| 国产三级久久久精品麻豆三级| 久久91综合国产91久久精品| 亚洲午夜久久久| 九九99精品久久久久久| 伊人久久无码精品中文字幕| 国产一级持黄大片99久久| 久久99久国产麻精品66| 国产免费久久精品99久久| 亚洲va久久久噜噜噜久久男同| 91亚洲国产成人久久精品网址| 久久受www免费人成_看片中文| 久久99精品久久久久久hb无码| 久久精品国产福利国产琪琪| 国产精品无码久久综合| 久久国产精品无| 亚洲精品高清一二区久久| 99久久精品免费看国产免费| 999久久久免费精品国产| 人妻久久久一区二区三区| 四虎久久影院| 狠狠色丁香久久婷婷综合图片| 国产精品久久久久天天影视| 亚洲午夜久久久久久噜噜噜| 中文字幕无码久久久| 一级做a爰片久久毛片毛片| 日日狠狠久久偷偷色综合免费 | 久久国产热精品波多野结衣AV | 久久久久人妻一区二区三区vr| 国产精品亚洲综合专区片高清久久久 | 精品久久久中文字幕人妻| 热99re久久国超精品首页| 欧美日韩中文字幕久久伊人| 亚洲愉拍99热成人精品热久久| 欧美午夜A∨大片久久 |