我正在上一门关于操作系统的大学课程,我们正在学习如何将二进制转换为十六进制,十进制转换为十六进制等,今天我们刚刚学习了如何使用两个数字的补数(~number + 1)将有符号/无符号数字存储在内存中。
我们有几个练习要在纸上做,我希望在把我的工作交给老师之前能够验证我的答案。我为前几个练习写了一个c++程序,但现在我被困在如何用以下问题验证我的答案:
char a, b;
short c;
a = -58;
c = -315;
b = a >> 3;
我们需要在内存中给出a b c的二进制表示。
我已经在纸上做过了,它给了我以下结果(所有的二进制表示在内存的数字之后的二补):
A = 00111010(它是一个char,所以是1字节)
B = 00001000(它是一个char,所以是1字节)
C = 11111110 11000101(它是短的,所以是2字节)
有办法证实我的答案吗?在c++中是否有一种标准的方法来显示一个数字在内存中的二进制表示,或者我必须自己编写每一步(计算两者的补数,然后转换为二进制)?我知道后者不会花很长时间,但我很好奇是否有一个标准的方法来做到这一点。
#include <iostream>
#include <cmath> // in order to use pow() function
using namespace std;
string show_binary(unsigned int u, int num_of_bits);
int main()
{
cout << show_binary(128, 8) << endl; // should print 10000000
cout << show_binary(128, 5) << endl; // should print 00000
cout << show_binary(128, 10) << endl; // should print 0010000000
return 0;
}
string show_binary(unsigned int u, int num_of_bits)
{
string a = "";
int t = pow(2, num_of_bits); // t is the max number that can be represented
for(t; t>0; t = t/2) // t iterates through powers of 2
if(u >= t){ // check if u can be represented by current value of t
u -= t;
a += "1"; // if so, add a 1
}
else {
a += "0"; // if not, add a 0
}
return a ; // returns string
}
在c++ 20中,你可以使用std::format来做到这一点:
unsigned char a = -58;
std::cout << std::format("{:b}", a);
输出:
11000110
在旧的系统上,你可以使用{fmt}库,std::format是基于这个库的。{fmt}还提供了print函数,使这更容易和更有效(godbolt):
unsigned char a = -58;
fmt::print("{:b}", a);
免责声明:我是{fmt}和c++ 20 std::format的作者。
如果你想显示任何对象的位表示形式,而不仅仅是整数,记得先将其重新解释为一个char数组,然后你可以将该数组的内容打印为十六进制,甚至是二进制(通过bitset):
#include <iostream>
#include <bitset>
#include <climits>
template<typename T>
void show_binrep(const T& a)
{
const char* beg = reinterpret_cast<const char*>(&a);
const char* end = beg + sizeof(a);
while(beg != end)
std::cout << std::bitset<CHAR_BIT>(*beg++) << ' ';
std::cout << '\n';
}
int main()
{
char a, b;
short c;
a = -58;
c = -315;
b = a >> 3;
show_binrep(a);
show_binrep(b);
show_binrep(c);
float f = 3.14;
show_binrep(f);
}
请注意,大多数常见的系统都是小端顺序的,因此show_binrep(c)的输出不是您期望的1111111 011000101,因为这不是它在内存中的存储方式。如果您正在寻找二进制的值表示,那么简单的cout << bitset<16>(c)就可以了。