如何获得具有不同比特集大小的比特集OR

问题描述 投票:3回答:3

使用时,

  std::bitset<5> op1 (std::string("01001"));
  std::bitset<5> op2 (std::string("10011"));

  std::cout << (op1|=op2) << std::endl;  

显然一切都很好。

但是我的问题是,如何使用两个不同大小的'std :: bitset's进行OR运算?如,

  std::bitset<11> op1 (std::string("101110011"));
  std::bitset<5> op2 (std::string("01001"));

  std::cout << (op1|=op2) << std::endl;

我无法在VS 2012中编译此代码。在这里我错过了什么?我不能对OR运算(以及XOR)使用不同大小的位集吗?这是平台特定的问题吗?

c++ binary bit bitset
3个回答
3
投票

接口不直接支持此功能。您可以改为构造一个临时位集:

// assuming op1 is larger
op1 |= std::bitset<op1.size()>(op2.to_ullong())

如果较大的位集的值不适合unsigned long long,则可以调用to_string


2
投票

您可以添加自定义运算符:

#include <iostream>
#include <bitset>
#include <limits>

namespace BitsetOperators {
namespace Detail {
    template<std::size_t A, std::size_t B, bool Less = A < B>
    struct Evaluate
    {
        static_assert(
               A <= std::size_t(std::numeric_limits<unsigned long long>::digits)
            && B <= std::size_t(std::numeric_limits<unsigned long long>::digits),
            "The bitset does not fit into an unsigned long long");

        typedef std::bitset<A> value_type;

        static value_type op_or(std::bitset<A> a, const std::bitset<B>& b) {
            return a |= value_type(b.to_ullong());
        }

        static value_type op_and(std::bitset<A> a, const std::bitset<B>& b) {
            return a &= value_type(b.to_ullong());
        }

        static value_type op_xor(std::bitset<A> a, const std::bitset<B>& b) {
            return a ^= value_type(b.to_ullong());
        }

        static bool op_eq(const std::bitset<A>& a, std::bitset<B> b) {
            return a.to_ullong() == b.to_ullong();
        }
    };

    template<std::size_t A, std::size_t B>
    struct Evaluate<A, B, true>
    {
        static_assert(
               A <= std::size_t(std::numeric_limits<unsigned long long>::digits)
            && B <= std::size_t(std::numeric_limits<unsigned long long>::digits),
            "The bitset does not fit into an unsigned long long");

        typedef std::bitset<B> value_type;

        static value_type op_or(const std::bitset<A>& a, std::bitset<B> b) {
            return b |= value_type(a.to_ullong());
        }

        static value_type op_and(const std::bitset<A>& a, std::bitset<B> b) {
            return b &= value_type(a.to_ullong());
        }

        static value_type op_xor(const std::bitset<A>& a, std::bitset<B> b) {
            return b ^= value_type(a.to_ullong());
        }

        static bool op_eq(const std::bitset<A>& a, std::bitset<B> b) {
            return b.to_ullong() == a.to_ullong();
        }
    };
} // namespace Detail


/// Operator A | B: The resulting bitset has the maximal size of A and B.
template <std::size_t A, std::size_t B>
inline typename Detail::Evaluate<A, B>::value_type
operator | (const std::bitset<A>& a, const std::bitset<B>& b) {
    return Detail::Evaluate<A, B>::op_or(a, b);
}

/// Operator A & B: The resulting bitset has the maximal size of A and B.
template <std::size_t A, std::size_t B>
inline typename Detail::Evaluate<A, B>::value_type
operator & (const std::bitset<A>& a, const std::bitset<B>& b) {
    return Detail::Evaluate<A, B>::op_and(a, b);
}

/// Operator A ^ B: The resulting bitset has the maximal size of A and B.
template <std::size_t A, std::size_t B>
inline typename Detail::Evaluate<A, B>::value_type
operator ^ (const std::bitset<A>& a, const std::bitset<B>& b) {
    return Detail::Evaluate<A, B>::op_xor(a, b);
}

/// Operator A == B
template <std::size_t A, std::size_t B>
inline bool operator == (const std::bitset<A>& a, const std::bitset<B>& b) {
    return Detail::Evaluate<A, B>::op_eq(a, b);
}

/// Operator A != B
template <std::size_t A, std::size_t B>
inline bool operator != (const std::bitset<A>& a, const std::bitset<B>& b) {
    return ! (a == b);
}

}  // namespace BitsetOperators


// Test
// ====

int main(int argc, const char * argv[])
{
    using namespace BitsetOperators;
    std::bitset<11> op1 (std::string("101110011"));
    std::bitset<5> op2 (std::string("01001"));
    std::cout << std::boolalpha;
    std::cout << (op1 | op2) << std::endl;
    std::cout << (op1 & op2) << std::endl;
    std::cout << (op1 ^ op2) << std::endl;
    std::cout << (op1 == op2) << std::endl;
    std::cout << (op1 != op2) << std::endl;
}

0
投票
using namespace std;

template <size_t startN, size_t endN>
bitset<endN> convert(bitset<startN> start)
{
    const size_t minBits = (startN < endN) ? startN : endN;
    const size_t min64Bits = (minBits - 1) / 64 + 1;
    bitset<endN> result;
    for (size_t n = 0; n < min64Bits; n++)
    {
        result <<= 64;
        result |= start.to_ullong();
    }
    return result;
}

int main()
{
    std::bitset<11> op1 (std::string("101110011"));
    std::bitset<5> op2 (std::string("01001"));
    std::cout << (op1|=convert<5, 11>(op2));
}

如果您的位集中有64位以上,则可以使用此函数进行转换。

© www.soinside.com 2019 - 2024. All rights reserved.