簡體   English   中英

帶有負值的無符號長整數

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM