如何在数组<bool>上使用位操作

How to use bitoperations on array<bool>

本文关键字:位操作 gt bool 数组 lt      更新时间:2023-10-16

对于一些性能敏感的项目(执行时间很关键,内存不是问题),我需要某种容器,它可以容纳中等大小(最多500个)的布尔值。大小在编译时是已知的,因此似乎有两个明显的选择:

bitset<500>array<bool,500>

在这些容器上,程序必须进行大量的位操作并读取/设置单个值。

到目前为止,我使用的是位集,但[]-运算符读取/设置元素的性能非常糟糕。由于数组明显优于这里的位集,所以我所需要的只是在这些数组上使用逻辑运算符的某种快速方法。

所以我想要的是:

array<bool,500> a,b,c;
c = b ^ a;   // ??? how to do it, need & and ^ 

我想应该有一些魔术用memcpy或类似的东西来做…但直到现在我都想不通。对整个数组进行迭代不是一种选择。(试过了,太慢了)

如果你不介意内存分配,你可以使用std::valarray,它有元素二进制运算符:

#include <valarray>
int main()
{
    std::valarray<bool> a(500),b(500),c(500);
    c = b ^ a;
}

现场演示。

或者,您可以重载相关运算符以隐藏循环/算法调用:

#include <array>
#include <cstddef>
template<std::size_t N>
std::array<bool, N> operator^(const std::array<bool, N>& a, const std::array<bool, N>& b)
{
  std::array<bool, N> c;
  for(std::size_t i = 0; i<N; ++i)
    c[i] = a[i] ^ b[i];
  return c;
}
int main()
{
    std::array<bool,500> a,b,c;
    c = b ^ a;
}

现场演示。您可以使用算法或任何其他您认为合适的方式编写运算符。

我想不出任何方法,只能迭代数组。但您可能能够一次迭代4个(或8个)元素,类似于这样(未经测试)。

// Size must be evenly divisible by sizeof(unsigned long)
std::array<char,500> a, b, c;
unsigned long *pa = (unsigned long *)(a.data());
unsigned long *pb = (unsigned long *)(b.data());
unsigned long *pc = (unsigned long *)(c.data());
while (size_t i=0; i<a.size()/sizeof(unsigned long); ++i)
  pc[i] = pa[i] ^ pb[i];

但是,很难想象在这个操作中胜过一个好的bitset实现。

long a[500/sizeof(long) + 1];
long b[500/sizeof(long) + 1];
long c[500/sizeof(long) + 1];
memset(a, 0, sizeof(a));
memset(b, 0, sizeof(b));
memset(c, 0, sizeof(c));
// init your bitset a and b here
// here is faster than iterating the 500 items array
for(unsigned int i = 0; i < 500/sizeof(long) + 1; i++)
{
    c[i] = a[i] ^ b[i];
}

这里的技巧是long在32位机器上是32位,但在64位机器上却是64位。

谢谢@Adam,我发现boost::dynamic_bitset提供了您所需要的精确批量操作。

您可能需要重载运算符。

#include <array>
#include <algorithm>
#include <functional>
using barray = std::array<bool, 4>;
barray operator^(barray const &a, barray const &b){
    barray res;
    std::transform(a.begin(), a.end(), b.begin(), res.begin(), std::bit_xor<bool>());
    return res;
}
#include <container_io.h>
#include <iostream>
int main(){
    barray a = {true, true, false, false},
           b = {true, false, true, false};
    std::cout<<(a ^ b)<<"n";
    return 0;
}

container_io.h是来自http://blog.csdn.net/cqdjyy01234/article/details/19234329这有助于打印容器。

此外,您也可以使用std::valarray。