如何以二进制形式打印(使用 cout)数字?

发布于 2024-12-03 17:37:06 字数 671 浏览 4 评论 0原文

我正在学习有关操作系统的大学课程,我们正在学习如何从二进制转换为十六进制,十进制转换为十六进制等,今天我们刚刚学习了如何使用二进制补码将有符号/无符号数字存储在内存中(~number + 1)。

我们需要在纸上做一些练习,我希望能够在将作业提交给老师之前验证我的答案。我为前几个练习编写了一个 C++ 程序,但现在我不知道如何通过以下问题验证我的答案:

char a, b;

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

b = a >> 3;

并且我们需要显示 内存中的二进制表示abc

我已经在纸上完成了它,它给了我以下结果(二进制补码后数字的内存中的所有二进制表示形式):

a = 00111010(它是一个字符,所以 1 个字节)

b = 00001000(它是一个字符,所以 1 个字节)

c = 11111110 11000101(很短,所以 2 个字节)

有没有办法验证我的答案? C++ 中是否有标准方法来显示数字内存中的二进制表示形式,或者我是否必须自己编写每个步骤(计算二进制补码,然后转换为二进制)?我知道后者不会花那么长时间,但我很好奇是否有标准方法可以做到这一点。

I'm following a college course about operating systems and we're learning how to convert from binary to hexadecimal, decimal to hexadecimal, etc. and today we just learned how signed/unsigned numbers are stored in memory using the two's complement (~number + 1).

We have a couple of exercises to do on paper and I would like to be able to verify my answers before submitting my work to the teacher. I wrote a C++ program for the first few exercises but now I'm stuck as to how I could verify my answer with the following problem:

char a, b;

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

b = a >> 3;

and we need to show the binary representation in memory of a, b and c.

I've done it on paper and it gives me the following results (all the binary representations in memory of the numbers after the two's complement):

a = 00111010 (it's a char, so 1 byte)

b = 00001000 (it's a char, so 1 byte)

c = 11111110 11000101 (it's a short, so 2 bytes)

Is there a way to verify my answer? Is there a standard way in C++ to show the binary representation in memory of a number, or do I have to code each step myself (calculate the two's complement and then convert to binary)? I know the latter wouldn't take so long but I'm curious as to if there is a standard way to do so.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(13

心清如水 2024-12-10 17:37:06

最简单的方法可能是创建一个 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';

The easiest way is probably to create an std::bitset representing the value, then stream that to 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';
新人笑 2024-12-10 17:37:06

使用即时转换为 std::bitset。没有临时变量,没有循环,没有函数,没有宏。

Live On Coliru

#include <iostream>
#include <bitset>

int main() {
    int a = -58, b = a>>3, c = -315;

    std::cout << "a = " << std::bitset<8>(a)  << std::endl;
    std::cout << "b = " << std::bitset<8>(b)  << std::endl;
    std::cout << "c = " << std::bitset<16>(c) << std::endl;
}

打印:

a = 11000110
b = 11111000
c = 1111111011000101

Use on-the-fly conversion to std::bitset. No temporary variables, no loops, no functions, no macros.

Live On Coliru

#include <iostream>
#include <bitset>

int main() {
    int a = -58, b = a>>3, c = -315;

    std::cout << "a = " << std::bitset<8>(a)  << std::endl;
    std::cout << "b = " << std::bitset<8>(b)  << std::endl;
    std::cout << "c = " << std::bitset<16>(c) << std::endl;
}

Prints:

a = 11000110
b = 11111000
c = 1111111011000101
高速公鹿 2024-12-10 17:37:06

在 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 的作者。

In C++20 you can use std::format to do this:

unsigned char a = -58;
std::cout << std::format("{:b}", a);

Output:

11000110

On older systems you can use the {fmt} library, std::format is based on. {fmt} also provides the print function that makes this even easier and more efficient (godbolt):

unsigned char a = -58;
fmt::print("{:b}", a);

Disclaimer: I'm the author of {fmt} and C++20 std::format.

你爱我像她 2024-12-10 17:37:06

如果要显示任何对象的位表示形式,而不仅仅是整数,请记住首先重新解释为 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) 有效。

If you want to display the bit representation of any object, not just an integer, remember to reinterpret as a char array first, then you can print the contents of that array, as hex, or even as binary (via 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);
}

Note that most common systems are little-endian, so the output of show_binrep(c) is not the 1111111 011000101 you expect, because that's not how it's stored in memory. If you're looking for value representation in binary, then a simple cout << bitset<16>(c) works.

妄想挽回 2024-12-10 17:37:06

C++ 中是否有标准方法来显示内存中数字的二进制表示形式 [...]?

没有。没有 std::bin,如 std::hexstd::dec,但输出数字二进制并不难你自己:

你通过屏蔽所有其他位、左移并重复你拥有的所有位来输出最左边的位。

(类型中的位数为 sizeof(T) * CHAR_BIT。)

Is there a standard way in C++ to show the binary representation in memory of a number [...]?

No. There's no std::bin, like std::hex or std::dec, but it's not hard to output a number binary yourself:

You output the left-most bit by masking all the others, left-shift, and repeat that for all the bits you have.

(The number of bits in a type is sizeof(T) * CHAR_BIT.)

开始看清了 2024-12-10 17:37:06

与已经发布的类似,只需使用位移位和掩码来获取位;可用于任何类型,作为模板(只是不确定是否有标准方法来获取 1 字节中的位数,我在这里使用了 8)。

#include<iostream>
#include <climits>

template<typename T>
void printBin(const T& t){
    size_t nBytes=sizeof(T);
    char* rawPtr((char*)(&t));
    for(size_t byte=0; byte<nBytes; byte++){
        for(size_t bit=0; bit<CHAR_BIT; bit++){
            std::cout<<(((rawPtr[byte])>>bit)&1);
        }
    }
    std::cout<<std::endl;
};

int main(void){
    for(int i=0; i<50; i++){
        std::cout<<i<<": ";
        printBin(i);
    }
}

Similar to what is already posted, just using bit-shift and mask to get the bit; usable for any type, being a template (only not sure if there is a standard way to get number of bits in 1 byte, I used 8 here).

#include<iostream>
#include <climits>

template<typename T>
void printBin(const T& t){
    size_t nBytes=sizeof(T);
    char* rawPtr((char*)(&t));
    for(size_t byte=0; byte<nBytes; byte++){
        for(size_t bit=0; bit<CHAR_BIT; bit++){
            std::cout<<(((rawPtr[byte])>>bit)&1);
        }
    }
    std::cout<<std::endl;
};

int main(void){
    for(int i=0; i<50; i++){
        std::cout<<i<<": ";
        printBin(i);
    }
}
如梦 2024-12-10 17:37:06

可重用函数:

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);
}

这适用于所有类型的整数。

Reusable function:

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

Usage:

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

This works with all kind of integers.

迷乱花海 2024-12-10 17:37:06

使用 std::bitset 答案和便捷模板:

#include <iostream>
#include <bitset>
#include <climits>

template<typename T>
struct BinaryForm {
    BinaryForm(const T& v) : _bs(v) {}
    const std::bitset<sizeof(T)*CHAR_BIT> _bs;
};

template<typename T>
inline std::ostream& operator<<(std::ostream& os, const BinaryForm<T>& bf) {
    return os << bf._bs;
}

像这样使用它:

auto c = 'A';
std::cout << "c: " << c << " binary: " << BinaryForm{c} << std::endl;
unsigned x = 1234;
std::cout << "x: " << x << " binary: " << BinaryForm{x} << std::endl;
int64_t z { -1024 };
std::cout << "z: " << z << " binary: " << BinaryForm{z} << std::endl;

生成输出:

c: A binary: 01000001
x: 1234 binary: 00000000000000000000010011010010
z: -1024 binary: 1111111111111111111111111111111111111111111111111111110000000000

Using the std::bitset answers and convenience templates:

#include <iostream>
#include <bitset>
#include <climits>

template<typename T>
struct BinaryForm {
    BinaryForm(const T& v) : _bs(v) {}
    const std::bitset<sizeof(T)*CHAR_BIT> _bs;
};

template<typename T>
inline std::ostream& operator<<(std::ostream& os, const BinaryForm<T>& bf) {
    return os << bf._bs;
}

Using it like this:

auto c = 'A';
std::cout << "c: " << c << " binary: " << BinaryForm{c} << std::endl;
unsigned x = 1234;
std::cout << "x: " << x << " binary: " << BinaryForm{x} << std::endl;
int64_t z { -1024 };
std::cout << "z: " << z << " binary: " << BinaryForm{z} << std::endl;

Generates output:

c: A binary: 01000001
x: 1234 binary: 00000000000000000000010011010010
z: -1024 binary: 1111111111111111111111111111111111111111111111111111110000000000
安静被遗忘 2024-12-10 17:37:06

我在玩在线竞技编码游戏时遇到过这个问题。这是一个可以快速实施并且相当直观的解决方案。它还避免输出前导零或依赖

std::string s;
do {
    s = std::to_string(r & 1) + s;
} while ( r>>=1 );

std::cout << s;

但您应该注意,此解决方案会增加您的运行时间,因此,如果您正在竞争优化或根本不竞争,您应该使用其中之一本页的其他解决方案。

I have had this problem when playing competitive coding games online. Here is a solution that is quick to implement and is fairly intuitive. It also avoids outputting leading zeros or relying on <bitset>

std::string s;
do {
    s = std::to_string(r & 1) + s;
} while ( r>>=1 );

std::cout << s;

You should note however that this solution will increase your runtime, so if you are competing for optimization or not competing at all you should use one of the other solutions on this page.

ぺ禁宫浮华殁 2024-12-10 17:37:06
#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
}
#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
}
鲜血染红嫁衣 2024-12-10 17:37:06

使用旧的 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

Using old C++ version, you can use this snippet :

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
海之角 2024-12-10 17:37:06

这是获取数字的二进制表示形式的真正方法:

unsigned int i = *(unsigned int*) &x;

Here is the true way to get binary representation of a number:

unsigned int i = *(unsigned int*) &x;
℡寂寞咖啡 2024-12-10 17:37:06

这是您要找的吗?

std::cout << std::hex << val << std::endl;

Is this what you're looking for?

std::cout << std::hex << val << std::endl;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文