2010-03-16 115 views
5

請參閱下面的簡單代碼:無符號長與負值

#include <iostream> 
#include <stdlib.h> 

using namespace std; 


int main(void) 
{ 
    unsigned long currentTrafficTypeValueDec; 
    long input; 
    input=63; 
    currentTrafficTypeValueDec = (unsigned long) 1LL << input; 
    cout << currentTrafficTypeValueDec << endl; 
    printf("%u \n", currentTrafficTypeValueDec); 
    printf("%ld \n", currentTrafficTypeValueDec); 
    return 0; 
} 

爲什麼printf()的顯示currentTrafficTypeValueDec(無符號長)與負值?

輸出是:

9223372036854775808 
0 
-9223372036854775808 

回答

3

樂趣位...

cout被打印成一個unsigned long數量,所有64位都顯著和打印爲無符號二進制整數(我認爲這裏的格式將%lu)。

printf(%u ...將輸入視爲正常的無符號整數(32位?)。這會導致33到64位丟棄 - 留下零。

printf(%ld ...將輸入視爲64位有符號數字,並將其打印出來。

您可能會發現最後一個printf令人困惑的事情是它給出了與cout相同的絕對值,但帶有負號。在查看無符號整數時,所有64位在生成整數值時都很重要。然而對於有符號數字,位64是符號位。當符號位被設置時(就像在你的例子中那樣),它表示剩餘的63位應被視爲2's compliment中表示的負數。只需將二進制值轉換爲十進制數即可打印正數。但是,對於負數,會發生以下情況:打印一個負號,XOR位1到63用二進制'1'位加1,結果並打印無符號值。通過刪除符號位(位64),最終得到63'0'位,與'1'位異或會給63位'1'位,加+1,整個事情就會翻轉,給你一個無符號整數64設置爲'1',其餘設置爲'0' - 這與cout得到的結果是相同的,但是作爲負數。

一旦你已經制定了爲什麼上面的解釋是正確的,你也應該能夠弄明白把它的this

13

你騙通過傳遞一個無符號值,而格式規範說這將是一個一個籤的printf。

+0

有趣的方式:) – Tim 2010-03-16 17:39:24

17

%d是簽名的格式化程序。將currentTrafficTypeValueDec(2到63的功率)的位重新解釋爲signed long給出負值。因此printf()打印一個負數。可能要使用%lu

1

該變量本身並不攜帶其類型。您指定打印它的類型。請嘗試:

printf("%lu \n", currentTrafficTypeValueDec); 

因爲ld meand長簽名是不正確的。

5

因爲您將1轉換爲變量的符號位。當您將其打印爲有符號值時,該值爲負值。

+0

+1,最好的答案。 – 2010-03-16 16:01:56

0

您正在打印%ld或長簽名小數。這就是爲什麼它返回一個負值。