2016-11-15 57 views
5

當我在string::npos上工作時,我發現了一些東西,並且在網絡上找不到任何解釋。爲什麼(18446744073709551615 == -1)是真的?

(string::npos == ULONG_MAX) 

(string::npos == -1) 

是真實的。

所以,我想這一點:

(18446744073709551615 == -1) 

這也是真實的。

怎麼可能?是因爲二元對話嗎?

+3

溢出含義:對你比較無符號和符號值 – Stargateur

+3

這不是未定義行爲。 – rubenvb

+1

18446744073709551615 = 2^64 -1 ...幽靈巧合? – lelloman

回答

5

string::npos被定義爲constexpr static std::string::size_type string::npos = -1;(或者如果它是在類定義中定義的,那將是constexpr static size_type npos = -1;但這真的不相關)。

負號轉換爲無符號類型(std::string::size_type基本上是std::size_t,它是無符號的)的環繞完全由標準定義。 -1包裝爲無符號類型的最大可表示值,在您的情況下爲18446744073709551615。請注意,確切的值是由實現定義的,因爲std::size_t的大小是實現定義的(但能夠保持所討論系統中可能的最大陣列的大小)。

1

根據C++標準(文檔號:N3337或文件號:N4296)std::string::npos被定義,其中的std :: string :: size_type的是一些無符號整數類型如下方式

static const size_type npos = -1; 

。所以std :: string :: npos等於-1是沒有什麼奇妙的。初始化器轉換爲std::string::npos的類型。

作爲該方程

(string::npos == ULONG_MAX) is true, 

那麼它意味着該類型std::string::npos在所使用的實施unsigned long已鍵入。這種類型通常對應於size_t類型。

在這個公式中

(18446744073709551615 == -1) 

左邊的文字有一定的無符號整數類型是否適合於存儲這麼大的文字。因此,通過傳播符號位,右操作數也轉換爲該無符號類型。由於左操作數代表它自己的類型的最大值,所以它們是相等的。

0

這是關於簽名溢出以及負數存儲爲二進制補碼的事實。這意味着要獲得負數的絕對值,您需要反轉所有位並添加一個。做一個8位比較時,255和-1有11111111相同的二進制值,這同樣適用於更大的整數

https://en.m.wikipedia.org/wiki/Two%27s_complement

+0

根據定義/標準,負數不會以2作爲補碼存儲。他們只會這樣做。 – rubenvb

+0

這裏沒有簽名溢出。 –

+0

這是依賴CPU架構,但大多數現代架構使用2s補充 – doron