如何将整数数组转换为位数组?

时间:2017-01-07 15:01:29

标签: c++ arrays bit-manipulation bits

我想要完成的是迭代8个整数的数组,并将每个整数转换成8位的二进制形式。我还希望将每个整数的8位存储到一个大小为64的单个整数数组中。这是我到目前为止还没有得到正确的数组。

int Data[8] = {0,0,190,42,0,0,2,33};   

int bits[64];

for(int j = 0; j < 64;j++){
  for(int i = 0; i < 8;++i){                                                                

      bits[j+i] = Data[i] & (1 << i) ? 1 : 0;                                                   

   }
} 

我想获得的数组如下。 (每个位都是它自己的元素)

{0000000000000000101111100010101000000000000000000000001000100001}

3 个答案:

答案 0 :(得分:1)

您必须为8个整数中的每一个处理8位,这些整数确实给出64位。但循环应该是:

for(int j = 0; j < 8;j++){   // loop on integers
  for(int i = 0; i < 8;++i){
      bits[8*j+i] = Data[j] & (1 << i) ? 1 : 0;
   }
}

答案 1 :(得分:0)

#include <cstdint>

int main()
{
    uint64_t Data[8] = { 0,0,190,42,0,0,2,33 };
    uint64_t bits = 0;

    for (int i = 0; i < 8; i++)
    {
        bits |= ((Data[i] & 0xFF) << (i * 8));
    }
    return 0;
}

尝试这样的方法,一次设置8位。

答案 2 :(得分:0)

注意:我认为Serge's answer是最有效的答案,但不是最容易重复使用的答案。因此,这个答案主要是针对通用的,因此可以重复使用任何大小的数组(假设目标数组足够大)。

您还可以通过std::bitset传递每个值,这样您就可以制作更通用的版本。

template<typename FromT, size_t FromSZ, typename ToT, size_t ToSZ>
void convert_to_bits(const FromT (&from_arr)[FromSZ], ToT (&to_arr)[ToSZ]) {
    static_assert(ToSZ >= ((sizeof(FromT) * CHAR_BIT) * FromSZ),
                  "Destination array must have enough elements to contain all bits of source array.");

    // Helper value, will be optimised out.
    constexpr size_t ELEMENT_SIZE = sizeof(FromT) * CHAR_BIT;

    // Handles bit manipulation cleanly.
    std::bitset<ELEMENT_SIZE> temp[FromSZ];

    // Populate temp.
    for (size_t i = 0; i < FromSZ; i++) { temp[i] = from_arr[i]; }

    // Fill destination array, one "row" (value in source array) at a time.
    for (size_t i = 0; i < FromSZ; i++) {
        size_t row = i * ELEMENT_SIZE;
        using std::fill;

        if (temp[i].none()) {
            // Row is all 0s, fill its part of destination array appropriately.
            fill(&to_arr[row], &to_arr[row + (ELEMENT_SIZE - 1)], 0);
        } else if (temp[i].all()) {
            // Row is all 1s, fill its part of destination array appropriately.
            fill(&to_arr[row], &to_arr[row + (ELEMENT_SIZE - 1)], 1);
        } else {
            // Row is mixed, do it one bit at a time.
            for (size_t j = 0; j < ELEMENT_SIZE; j++) {
                to_arr[row + j] = temp[i][j];
            }
        }
    }
}

可以用作:

int Data[8] = {0,0,190,42,0,0,2,33};
int bits[8 * (sizeof(int) * CHAR_BIT)] = {0};

convert_to_bits(Data, bits);

直播示例here

但是,这通常会比Serge Ballesta's answer略慢。为了检查这一点,我用this program测试了它,用五个版本宏中的每一个编译了五次:

[注意:所有比较的版本都是硬编码的ELEMENT_SIZE == 8,因此我的代码会给Serge的答案提供相同的结果,这样我就可以直接插入答案了。 static_assert已从convert_to_bits()中移除以容纳此内容。]

每个案例都编译成一个单独的程序,以(希望)最小化缓存,并在TutorialsPoint's online environment 1 中运行5次。未指定任何优化选项。

  • 使用-DSERGE一次,获得Serge的回答。

    sh-4.3$ g++ -DSERGE      main.cpp -std=c++14 -o serge
    
  • 使用-DTHROUGHconvert_to_bits()的标准用例。

    sh-4.3$ g++ -DTHROUGH    main.cpp -std=c++14 -o through
    
  • 使用-DDIRECT时,对于convert_to_bits()的手动内联版本。

    sh-4.3$ g++ -DDIRECT     main.cpp -std=c++14 -o direct
    
  • 使用-DFASTDIRECT后,应该(但可能不是)更有效的手动内联版本。

    sh-4.3$ g++ -DFASTDIRECT main.cpp -std=c++14 -o fastdirect
    
  • 使用-DNAIVE后,适用于未在适当时使用std::fill()的天真版本。

    sh-4.3$ g++ -DNAIVE      main.cpp -std=c++14 -o naive
    

平均......

  • serge获得了29.4分。
  • through获得了30.8分。
  • direct获得了30.6分。
  • fastdirect获得了32.8分。
  • naive获得了32.4滴答。

1:由于他们的C ++链接现在不适合我,我技术上使用了他们的在线Java环境。然而,这不是问题,因为他们的C ++和Java环境使用相同的沙箱,使用相同的工具;我注意到的唯一区别是1)提供了默认的“Hello World”程序(文件可以自由创建和重命名),以及2)“编译”和“执行”按钮被映射到的命令(可以是在菜单中更改)。这两种环境都可以免费使用GCC和Javac,从而可以从Bash shell轻松执行。