2009-11-03 124 views
10

前些天,I came across該構建體:便攜式如何將-1轉換爲無符號類型?

static_cast<size_type>(-1) 

在一些示例C++代碼,這很可能(取決於其中size_type是從細節)是等效於以下C:

(size_t)(-1) 

據我所知,它的工作原理是-1的二進制補碼算法的表示爲11111...1,因爲它具有儘可能多的位數,所以這是一種獲得最大值的快速方法,即無符號類型size_t可以容納。但是,我的理解是,C不保證會使用二進制補碼;如果C實現使用補碼,那麼它將比最大值小1,並且如果它使用符號幅度,它將剛好超過最大值的一半。

是否存在一些我不知道的皺紋,確保這個工作正確無論使用的有符號整數的表示如何? C和C++有什麼不同(許多令人驚訝的事情)?

+3

如果你想確定,總是有'std :: numeric_limits :: max()'。 – UncleBens 2009-11-03 15:23:29

+0

我認爲這樣的情況是爲什麼你的語言中有static_cast和reinterpret_cast - static_cast可以給你一些可預測的(並且因此有用),但是在某些平臺上可能有較慢的實現,而reinterpret_cast可以取消任何保證。 – Kylotan 2009-11-03 15:46:24

+3

這是恕我直言最好的方式來獲得所有的比特數。使用'〜0U'的選項也可以工作(如果你忘記添加'U'並執行'〜0',例如所有的比特位都是0),但是使用'-1'轉換爲'unsigned'類型它始終獨立於類型工作。所以你不必關心使用'ULL'或者首先強制轉換爲'unsigned short' - 你可以使用'-1'並賦值:)參見http://stackoverflow.com/questions/809227/它是安全的 - 使用 - 將所有位設置爲真1 – 2009-11-03 15:50:34

回答

19

對無符號算術的要求保證將-1轉換爲無符號類型將產生目標類型可能的最大數目。 C99,§6.2.5/ 9:「...無法用結果無符號整數類型表示的結果減少的模數大於可由結果類型表示的最大值的數。

這是在C和C相同++(在C++標準,類似的措詞在腳註41發現 - 這不是標準化的,但它說明的其它措辭是)。

+6

對於C++,規範性措辭在'4.7/2 ' – 2009-11-03 15:41:09

+0

謝謝!這正是我想知道的皺紋 – Pillsy 2009-11-03 15:53:51

14

要在「安全」方面,並做「正確的」(C++)的方式,值得看的STL:的

std::numeric_limits<size_t>::max() 
+3

唯一的缺點是該值不是一個常量表達式。您可以使用'integral_constant ',但'integral_constant :: max()>'不起作用:( – 2009-11-05 16:21:36

2

如果你正在尋找得到最大(或最小)值一種便攜式的某種類型,最好使用如下的標準numeric_limits類。

#include <limits> 

size_type max = std::numeric_limits<size_type>::max() 
size_type min = std::numeric_limits<size_type>::min() 

我懷疑這些函數的某些實現可能會使用您所描述的轉換作爲平臺最優化方式來獲取最小值/最大值。

5

「據我所知,它的工作原理是-1表示二進制補碼算術......」。

不,它並不是基於這個事實。它基於標準的要求,被轉換爲N位無符號類型的單值必須產生一個無符號值,它與原始有符號模2^N「相等」。

它必須以這種方式工作,而不管實施使用的簽名表示。在2的補碼情況下,它本身就是這樣工作的,但對於其他表示,編譯器將不得不做額外的工作以滿足標準要求。

+0

呃......公平:標準的寫法正好可以讓CPU直接執行2的補碼運算,當然不是**不正確**在解釋中引用2的補碼語言標準的存在是爲了滿足硬件和用戶的需求,而不是相反。 – 2009-11-03 18:51:02

+0

我同意「滿足用戶的需求」部分。硬件的需求「?No. – AnT 2009-11-03 19:22:47

+0

我之前已經寫下了答案,當我讀到它們時,」值是'UINT_MAX',因爲在二進制補碼中'-1'是全位1「。簡單地把它倒過來r,我會upvote這個答案。 – 2009-11-03 19:56:28

相關問題