我正在上一门关于操作系统的大学课程,我们正在学习如何将二进制转换为十六进制,十进制转换为十六进制等,今天我们刚刚学习了如何使用两个数字的补数(~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++中是否有一种标准的方法来显示一个数字在内存中的二进制表示,或者我必须自己编写每一步(计算两者的补数,然后转换为二进制)?我知道后者不会花很长时间,但我很好奇是否有一个标准的方法来做到这一点。


当前回答

可重用的功能:

template<typename T>
static std::string toBinaryString(const T& x)
{
    std::stringstream ss;
    ss << std::bitset<sizeof(T) * 8>(x);
    return ss.str();
}

用法:

int main(){
  uint16_t x=8;
  std::cout << toBinaryString(x);
}

这适用于所有的整数。

其他回答

如果你想显示任何对象的位表示形式,而不仅仅是整数,记得先将其重新解释为一个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)就可以了。

使用旧的c++版本,你可以使用下面的代码段:

template<typename T>
string toBinary(const T& t)
{
  string s = "";
  int n = sizeof(T)*8;
  for(int i=n-1; i>=0; i--)
  {
    s += (t & (1 << i))?"1":"0";
  }
  return s;
}

int main()
{
  char a, b;

  short c;
  a = -58;
  c = -315;

  b = a >> 3;

  cout << "a = " << a << " => " << toBinary(a) << endl;
  cout << "b = " << b << " => " << toBinary(b) << endl;
  cout << "c = " << c << " => " << toBinary(c) << endl;
}

a = => 11000110
b = => 11111000
c = -315 => 1111111011000101

最简单的方法可能是创建一个表示值的std::bitset,然后将其流到cout。

#include <bitset>
...

char a = -58;
std::bitset<8> x(a);
std::cout << x << '\n';

short c = -315;
std::bitset<16> y(c);
std::cout << y << '\n';

可重用的功能:

template<typename T>
static std::string toBinaryString(const T& x)
{
    std::stringstream ss;
    ss << std::bitset<sizeof(T) * 8>(x);
    return ss.str();
}

用法:

int main(){
  uint16_t x=8;
  std::cout << toBinaryString(x);
}

这适用于所有的整数。

在c++中是否有一种标准的方法来显示内存中数字[…]的二进制表示?

不。没有std::bin,像std::hex或std::dec,但是你自己输出一个数字二进制并不难:

你输出最左边的位,通过屏蔽所有其他的位,左移,并对所有的位重复这一步骤。

(类型的比特数是sizeof(T) * CHAR_BIT。)