2013-04-03 56 views
1

以下代碼:整數溢出操作

UINT32 dword = 4294967295; 

if(dword + 1 != 0) // condition 

在這樣的操作是有,最大的(全)寄存器(對建築繳費)總是使用任何保修嗎?以上條件在64位模式下始終爲真,而在32位模式下爲假。

+0

我相信標準說明整數溢出會發生什麼,儘管我不記得具體情況。當然'UINT32'在32位和64位體系結構上的大小相同,所以你可以期望它的行爲相同。 – 2013-04-03 23:10:43

+0

@MarkRansom:無符號溢出循環。簽名溢出具有未定義的行爲。 – 2013-04-03 23:31:57

回答

3

這取決於UINT32究竟是什麼類型。

如果它是一個無符號的類型(如你所期望的),那麼結果是保證模可以代表+ 1的最大值減小,所以這樣的代碼:

if (std::numeric_limits<T>::is_unsigned) 
    assert(std::numeric_limits<T>::max()+1==0); 

...應該成功。 OTOH基於名稱,我們通常認爲無論實現方式,寄存器大小等都是32位類型,所以我們希望不管是什麼,都會得到相同的結果。

編輯:[抱歉,不得不停下來喂寶寶幾分鐘]我應該補充一些細節。雖然我們當然可以希望它在實踐中不太可能,但是可以想象的是,UINT32確實可以(比如說)是一個16位的unsigned short。爲了討論,我們假設int是32位。

在這種情況下,dword+1將涉及unsigned shortint(隱含類型1)之間的數學。在這種情況下,dword實際上被初始化爲65535。然後,當你做了另外,65535將提升到32位int,並添加1int,那麼結果將是65536

至少在理論上,如果UINT32是無符號的32位類型(正如我們所期望的),則可能發生相同的基本事件,但int是64位類型。再次,dword將被提升爲int之前做數學,所以數學將完成64位數量,而不是32位,所以(再次)的結果不會繞回到0.

+0

使用'std :: numeric_limits :: is_unisgned'使我的代碼聞到紫色:P – 2013-04-03 23:19:01

+0

「減少的模可以表示的最大值*」加一* – 2013-04-03 23:31:06

+0

@KeithThompson:糟糕,很正確。謝謝。 – 2013-04-03 23:32:28