[英]Unsigned long with negative value
請參閱下面的簡單代碼:
#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(unsigned long)?
輸出是:
9223372036854775808
0
-9223372036854775808
%d
是簽名格式化程序。 將currentTrafficTypeValueDec
(2到63次冪)的位重新解釋為帶signed long
給出負值。 因此printf()
打印一個負數。
也許你想用%lu
?
你通過傳遞一個無符號值來欺騙printf,而格式規則說它將是一個簽名的。
因為您將1
移動到變量的符號位。 當您將其打印為有符號值時,它是否定的。
有點樂趣......
cout
將數字打印為無符號長整數,所有64位都很重要,打印為無符號二進制整數(我認為這里的格式為%lu
)。
printf(%u ...
將輸入視為普通的無符號整數(32位?)。這會導致位33到64下降 - 保留為零。
printf(%ld ...
將輸入視為64位有符號數,並將其打印出來。
你可能會發現最后一個printf
令人困惑的事情是它提供與cout
相同的絕對值,但帶有減號。 當作為無符號整數查看時,所有64位在產生整數值時都是重要的。 但是對於帶符號的數字,第64位是符號位。 當符號位置位時(如您的示例中所示),它表示剩余的63位將被視為2的補碼中表示的負數。 只需將二進制值轉換為十進制即可打印正數。 但是對於負數,會發生以下情況:打印一個負號,XOR位1到63,二進制“1”位,將結果加1並打印無符號值。 通過丟棄符號位(第64位),最終得到63'0'位,與'1'位進行異或,得到63'1'位,加上+1,整個事物翻轉,得到一個帶位的無符號整數64設置為'1',其余設置為'0' - 這與cout
BUT相同,為負數。
一旦你弄清楚為什么上面的解釋是正確的,你也應該能夠理解這一點
變量本身不具有其類型。 您指定printf其類型。 嘗試:
printf("%lu \n", currentTrafficTypeValueDec);
因為ld
meand long簽名並不是真的。
您正在打印%ld
或長簽名小數。 這就是它返回負值的原因。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.