C ++中变量的位表示形式

时间:2018-10-27 19:48:00

标签: c++

我希望有人可以帮助我解决这个问题。 我有这个C ++程序,它将能够打印一些变量的位表示。

#include <iostream>
#include <bitset>

//macro for extracting the ith bit from a given char.
#define EXTRACTBIT(ith,ch)(std::cout<<(ch & (1 << ith) ? 1 : 0))

/*printlnbits is a function which prints the bit representation of a variable (least 
significant bit must be shown on the right) followed by its size (in bits).*/

template <typename T> void printlnbits(T v)
{                                         
   const int v_size = sizeof(v) * 8;
   int j=0;
   char* ch = reinterpret_cast<char*>(&v);

   for (int n = v_size - 1; n >= 0; --n)
   {
       j++;
       EXTRACTBIT(n, *ch);
       if (j == 8)
       {
          std::cout << " ";
          j = 0;
       }
   }
   std::cout << "\t" << v_size << std::endl;
}
struct foo {
   int a = 2;
   char b = -1;
   unsigned long long int x = 1LLU << 63;
};

int main()
{
   const char a = 'a';
   const int b = -1L;
   const unsigned c = 1<<31;
   const float d = -0.0f;
   const long long unsigned e = 1LLU<<40;
   const foo f;
   printlnbits(a);
   printlnbits(b);
   printlnbits(c);
   printlnbits(d); 
   printlnbits(e);
   printlnbits(f); 
   return 0;
}

代码输出: code output

问题出在def变量上。它们的位表示不正确。我不知道我的代码有什么问题。我在C ++中有点新。有人可以帮忙吗????

3 个答案:

答案 0 :(得分:2)

您永远不会将指针ch递增到要检查的字节。因此,您需要反复检查相同的字节。同时使用全局位索引n代替j

#include <iostream>
#include <memory>
#include <climits>

template <typename T> void
printlnbits(T const & v)
{                                   
   auto const p_bytes_begin{reinterpret_cast<unsigned char const *>(::std::addressof(v))};
   auto const p_bytes_end{p_bytes_begin + sizeof(v)};
   auto p_byte{p_bytes_begin};
   auto bit_index_in_byte{0};
   for(;;)
   {
       ::std::cout << (((*p_byte) bitand (1 << bit_index_in_byte)) ? '1' : '0');
       ++bit_index_in_byte;
       if(CHAR_BIT == bit_index_in_byte)
       {
          ::std::cout << " ";
          bit_index_in_byte = 0;
          ++p_byte;
          if(p_bytes_end == p_byte)
          {
              break; // for(;;)
          }
       }
   }
   ::std::cout << "    " << (sizeof(v) * CHAR_BIT) << " bits" << ::std::endl;
}

online compiler

10000110     8 bits
11111111 11111111 11111111 11111111     32 bits
00000000 00000000 00000000 00000001     32 bits
00000000 00000000 00000000 00000001     32 bits
00000000 00000000 00000000 00000000 00000000 10000000 00000000 00000000     64 bits
01000000 00000000 00000000 00000000 11111111 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001     128 bits

答案 1 :(得分:1)

我在这里看不到“ ch”的增加

  for (int n = v_size - 1; n >= 0; --n)
   {
       j++;
       EXTRACTBIT(n, *ch);
       if (j == 8)
       {
          std::cout << " ";
          j = 0;
       }
   }

您只看到第一个字节。

答案 2 :(得分:0)

使用此:

template<typename T>
void print(T v) {
    int s = sizeof(T) * 8;
    for (int i = s - 1; i >= 0; i--) {
        if ((i+1) % 8 == 0) std::cout << ' ';
        std::cout << ((v & 1 << i)? 1 : 0);
    }
    std::cout << '\n';
}

对于浮点类型和其他类型,您可以简单地使用:

std::cout << std::bitset<int(sizeof(float) *8 )>(d) << '\n';