我正在读一本c++书,试图学习一些东西。我被一件事卡住了,一点也不。我知道它翻转了所有的位,但它不是我在c++中期望的工作方式。以下是相关代码。
letter = 'A'; // dec = 65 hex = 0x41 binary = 0100 0001
cout << endl << "Bitwise NOT" << endl;
cout << "Letter: " << letter << " = " << insertSpaces(toBinary(letter)) << endl;
int notletter = ~letter;
cout << "~Letter: " << notletter << endl;
string insertSpaces(string binary)
// insert spaces into a binary number string for readability
{
int pos = 4;
int len = binary.length();
while (pos < len)
{
binary.insert(pos, " ");
pos = pos + 5; // 5 because it includes space
len++; // space makes length longer
}
return binary;
}
string toBinary(int letter)
{
string result = "";
while (letter > 0)
{
result = toString(letter % 2) + result;
letter /= 2;
}
int rem = result.length() % 4;
if (rem > 0)
{
int zeros = 4 - rem;
for (int i = 0; i < zeros; i++)
result = "0" + result;
}
return result;
}
输出如下:
Bitwise NOT
Letter: A = 0100 0001
~Letter: -66
答案应该是190或10111110的二进制,为什么我得到-66?我用的是Visual c++ 2010
使用无符号整数而不是有符号整数。你得到一个负数的原因是因为今天大多数计算机使用2的补码。
这是你的数据在按位not之前和之后的样子:
before | after
0100 0001 | 1011 1110
(实际上那里可能有32位,因为你使用的是int
而不是char
;这里最好使用的类型可能是uint8_t
)
在二进制补码中,如果最高位为1,则该数为负数。不是之后,就是。在2的恭维中,要求一个数的负数,你取位0,然后加1。如果你取1011 1110
逆,就得到0100 0001
。现在添加一个,得到0100 0010
。如果把它转换成小数,就得到66。加上第一个位是1的减号,你得到-66,意想不到的值
您正在处理的是二进制补码中的有符号数。该值已超过最大正值(127),并被换行到负空格。
您可以将其打印为无符号字符/整数(即(unsigned int)notletter
或static_cast<unsigned int>(notletter)
)。