2015-02-06 36 views
2

如果我用C總結無符號和有符號整數,相同或不同的答案?

int main() 
{ 
    int x = <a number> 
    int y = <a number> 
    unsigned int v = x; 
    unsigned int w = y; 
    int ssum = x * y; 
    unsigned int usum = v * w; 
    printf("%d\n", ssum); 
    printf("%d\n", usum); 
    if(ssum == usum){ 
     printf("Same\n"); 
    } else { 
     printf("Different\n"); 
    } 

return 0; 
} 

有以下代碼,將打印的是什麼?難道是因爲等於符號和無符號,如果你有一個像-1負,當它被分配給int x成爲0xFF的,而且會產生相同的結果,那麼,如果你想要做1 +( - 1),如果你以簽名的方式得到-2 = 0xFE,並且由於無符號變量將被設置爲0xFF,所以如果添加它們,您仍然可以獲得0xFE。對於2 +(-3)或-2 + 3也是如此,最後十六進制值是相同的。那麼在C中,當它看到signedSum == unsignedSum時會看到什麼?它不關心一個實際上是一個大數目,另一個是-2,只要1和0是相同的?

是否存在將使這不是真的任何價值?

+0

號,C是相反的,它看起來什麼值表示,不關心1和0。 '-1 + -1'總是'-2' – 2015-02-06 23:02:54

+3

注意* signed overflow *是**未定義的行爲**。你會經常閱讀它,但是你不能**依靠這個。另一方面,無符號*溢出是明確的二進制補碼環繞。 – EOF 2015-02-06 23:06:40

+0

@EOF:*幾乎*正確。無符號算術的環繞與2的補碼無關。 (嚴格來說,它不是「溢出」。) – 2015-02-06 23:22:00

回答

2

你給的例子在C是不正確此外,之間的轉換符號和無符號類型保留位模式不需要(轉換是值),但仍存在一些交涉位模式將被保留。

有些情況下,操作的結果將是相同的,而這裏的情況,結果會有所不同。

  • 如果增加兩個int S的(實際)總和將溢出的int (即值範圍之外,一個int可以代表)的結果是 未定義的行爲。在這一點上可能發生任何事情(包括 程序異常終止) - 隨後轉換爲unsigned不會改變任何內容。
  • 用負的值轉換的intunsigned int使用模算術 (模最大值,一個unsigned可以 表示,加1)。這由標準明確定義,但 表示-1(類型int)將轉換爲無符號可表示的最大值(即UINT_MAX,在<limits.h>中指定的實現定義的 值)。
  • 同樣,添加unsigned int類型的兩個變量總是使用 模運算。

因爲這樣的事情,你的問題「哪個會產生最多的?」沒有意義。

+0

那麼這是依賴於編譯器還是機器?我想用我上面編輯的真實代碼來嘗試這個,當我運行這個時,我得到了所有數字的「相同」,無論是+ -1,2,3還是+ -unit max。我從打印報表中得到相同的編號。爲什麼我的結果與你所說的不一樣? – 2015-02-07 00:14:30

+0

該標準明確規定了一組最低要求,並故意留下一些未定義的內容(如帶符號的整型類型的溢出),實現定義的(如UINT_MAX或INT_MAX等值),未指定等。這意味着行爲可以並且在編譯器,機器,甚至是編譯器設置 - 但是如果你堅持使用一個編譯器和機器(並且不會影響代表類型的設置,如果你的編譯器提供了這些設置的話)。 – Rob 2015-02-07 01:24:53

相關問題