我知道〜操作符不能操作。但我無法確定下列程序的輸出(即-65536)。究竟發生了什麼?不對整數值進行操作
#include <stdio.h>
int main(void) {
int b = 0xFFFF;
printf("%d",~b);
return 0;
}
我知道〜操作符不能操作。但我無法確定下列程序的輸出(即-65536)。究竟發生了什麼?不對整數值進行操作
#include <stdio.h>
int main(void) {
int b = 0xFFFF;
printf("%d",~b);
return 0;
}
當您將16位值0xffff
分配給32位整數b
時,變量b
實際上變爲0x0000ffff
。這意味着當您執行按位補碼時,它變爲0xffff0000
,它與小數點-65536
相同。
C++中的〜運算符是位運算符NOT運算符。它也被稱爲按位補碼。這是翻轉你的簽名的整數的位。
舉例來說,如果你有
int b = 8;
// b in binary = 1000
// ~b = 0111
這將翻轉,表示爲初始整數位。
〜b = 0111只有int是4位。它最有可能是1111111111110111二進制,假設32位整數 – franji1
沒錯,但他沒有提供任何有關架構的信息 –
對於整數每一個二進制數,按位非運算變爲全1變成0,和全0變爲1秒。
所以十六進制0xFFFF
是二進制1111 1111 1111 1111
(每個十六進制字符是4位,和F,爲15,是所有四位全爲1)
您設置一個32位整數的是,這意味着它的現在:
0000 0000 0000 0000 1111 1111 1111 1111
然後你不是吧,這是這意味着:
1111 1111 1111 1111 0000 0000 0000 0000
最高位是簽名位(無論是正還是負),因此它給出了一個負數。
這是做位補,此輸出可以幫助您瞭解正在發生的事情更好:
std::cout << std::hex << " b: " << std::setfill('0') << std::setw(8) << b
<< " ~b: " << (~b) << " -65536: " << -65536 << std::endl ;
,我得到如下結果:
b: 0000ffff ~b: ffff0000 -65536: ffff0000
所以我們設置低16位1
這讓我們0000ffff
,然後我們做一個補充,將低16位0
高端16位設置爲1
這讓我們ffff0000
等於牛逼-65536
十進制。
在這種情況下,因爲我們與位運算的工作,檢查十六進制數據爲我們提供了一些見解,到底是怎麼回事。
假設32位整數
int b = 0xFFFF; => b = 0x0000FFFF
~b = 0xFFFF0000
頂部位現在設置。假設2s complement,這意味着我們有一個負數。反轉其他位,然後加1給出0x00010000
或65536
結果取決於您的平臺上簽名整數的表示方式。最常見的表示法是使用「二進制補碼」算法表示負值的32位值。也就是說,負值-x
由與無符號值2^32 - x
相同的位模式表示。
在這種情況下,原始位模式具有低16位設置:
0x0000ffff
的按位求反清除這些位,並設置高16位:
0xffff0000
解釋此作爲負數給出值-65536
。
通常情況下,當您在逐位算術中進行混亂時,您會希望使用無符號類型,以避免這種混淆。
您的評論:
如果是 'B' 不..然後輸出應爲0,但爲什麼-65536
建議你期待的結果:
uint32_t x = 0xFFFF;
uint32_t y = ~x;
爲0
。
這將是一個邏輯不是真正的操作,如:
uint32_t x = 0xFFFF;
uint32_t y = !x;
...但operator~
不是邏輯沒有,但一個按位沒有。有一個很大的不同。
邏輯返回0表示非0值(對於真值爲false),對於0值則返回1。
但是按位並不反轉給定值中的每一位。因此,0xF
的二進制NOT:
0x0F: 00000000 11111111
~0x0F: 11111111 00000000
不是零,而是0xF0。
所以你已經知道它到底是什麼,你的問題比 – aaronman
@suspectus請不要將C標籤添加到C++標籤的問題,反之亦然。這些是不同的語言。如果您認爲問題是C而不是C++,並且標記爲C++錯誤,那麼在添加C標記時應該刪除C++標記。 – Dukeling
@aaronman如果它不是'b',那麼輸出應該是0,但是爲什麼-65536 –