C++有/無符號數字型別之間的比較
阿新 • • 發佈:2018-12-11
在kmp.cpp中的迴圈,迴圈判斷下標(int型別)與std::string::size_type型別比較發生了迴圈只執行一部分的問題。
int i = j = 0
while (i < s.size() && j < p.size())
{
// some codes may make j -1;
}
在這段程式碼當中,出現了j < p.size()但是卻不執行迴圈的情況。原因是當j為-1的時候,j > p.size()
, 因為unsigned/signed
型別。
string s = "ababababababababababababababababababcaHello world!"; int i = -1; cout << "i < s.size():" << (i < s.size()) << endl; size_t ui = i; cout << "ui:" << ui << endl; cout << "ui == i:" << (ui == i) << endl; /* ouputs: i < s.size():0 ui:18446744073709551615 ui == i:1 */
string::size()
型別是無符號型別。所以使用關係運算符會出現問題。但是繼續觀察剩下部分demo,發現ui==i
為true
,而且ui
的位元組隨著32/64位機器改變,底層的比較依舊為true
,這是一個feature。應該設計機組的底層實現的知識。負數的二進位制表達。
檢視《計算機組成與設計:硬體/軟體介面(亞洲版)》2.4 signed and unsigned numbers部分知識得到: Negating this number by inverting the bits and adding one.
所以-1對於int32
的二進位制為:00000...001 -> 111...1110, + 1, 11111...111,32個1。對於size_t ui = 18446744073709551615 為2 ^ 64 - 1, 也就是111111...1111, 64個1,所以他們被判斷相等。
unsigned long ul = 0xFFFFFFFFFFFFFFFF; // 16個F, 16^16-1
int si = -1;
cout << ul << endl;
cout << "si==ul:" << (ul == si) << endl;
/*
18446744073709551615
si==ul:1
*/
可以看出,應該是從右邊開始進行邏輯與比較,大小為小的一方。