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

            国产成人精品久久亚洲高清不卡 | 思思久久99热免费精品6| 综合久久国产九一剧情麻豆| 亚洲天堂久久精品| 久久久久久无码Av成人影院| 亚洲精品无码成人片久久| 国产成人久久精品一区二区三区 | 国产精品青草久久久久婷婷| 亚洲欧美久久久久9999| 久久久久久国产精品无码超碰| 青青草原综合久久大伊人精品| 日韩久久久久中文字幕人妻| 精品久久久久久亚洲精品 | 久久91这里精品国产2020| 久久人人爽人人爽人人片av高请| 久久国产热精品波多野结衣AV| 久久亚洲国产精品成人AV秋霞 | 久久99热只有频精品8| 国产毛片久久久久久国产毛片| 亚洲国产精品久久久天堂| 国产精品99久久久久久宅男| 无码人妻精品一区二区三区久久| 久久久无码精品午夜| 一本一道久久精品综合| 久久久WWW成人免费毛片| 久久99精品久久久久久秒播| 久久久午夜精品福利内容| 久久国产免费观看精品| 久久久久人妻一区二区三区vr | 国产精品久久久久久久久鸭| 久久SE精品一区二区| 久久香综合精品久久伊人| 久久一区二区三区99| 久久99精品九九九久久婷婷| 久久伊人影视| 久久免费视频6| 亚洲精品无码久久久| 国内精品久久久久影院薰衣草 | 久久久久亚洲AV无码专区体验| 久久综合色老色| 色综合久久无码五十路人妻|