Define Bitset Size At Initialization

Define bitset size at initialization?

Boost has a dynamic_bitset you can use.

Alternatively, you can use a vector<bool>, which (unfortunately) is specialized to act as a bitset. This causes a lot of confusion, and in general is considered a bad idea. But that's how it works, so if that's what you need, you might as well use it, I suppose.

Use a variable to set the size of a bitset

It can't be done. The size of a std:bitset is a template parameter, so it has to be a compile-time constant.

A few choices that can/could work would be:

  1. Set an upper bound on the size, use a bitset of that size, and just ignore the extra bits.
  2. Switch to an std::vector<bool>. This has caveats, but provides roughly similar basic capabilities as a bitset.
  3. Switch to a Boost dynamic_bitset. This will let you specify the size as a parameter to the ctor, rather than a template parameter, so it doesn't need to be a compile-time constant.

There are undoubtedly other possibilities, of course. Personally, my first choice would probably be the Boost dynamic_bitset.

Initializing very large C++ std::bitset at compile time

You didn't really split the literal. It gets concatenated for compilation anyways. You are getting limited by the compiler. I don't think there's a way to increase this limit in MSVC.

You can split it into two literals, initialize two bitsets, shift 1st part and OR with the other.

Something like:

#include <iostream>
#include <string>
#include <bitset>


using namespace std;
int main()
{
std::bitset<8> dest("0110");
std::bitset<8> lowBits("1001");

dest <<= dest.size()/2;
dest |= lowBits;
std::cout << dest << '\n';
}

If you look at the clang compiler output at -02, it gets optimized to loading 105 which is 01101001.

My testing shows that if you swap 8 for 1<<16 it uses SSE, so it should be pretty safe bet. It didn't drop the literals like in case of 8 or 16, so there might be some runtime overhead, but I am not sure if you can do much better.

EDIT:

I did some more tests, here is my playground:

#include <iostream>
#include <string>
#include <bitset>


using namespace std;
int main()
{
//static const std::bitset<16> set1( "01100110011001100110011001100110");
static const std::bitset<16> set2(0b01100110011001100110011001100110);

static const std::bitset<16> high(0b01100110);
static const std::bitset<16> low (0b01100110);
static const std::bitset<16> set3 = (high << 8) | low;
std::cout << (set3 == set2) << '\n';
}

I couldn't get compile time optimization for const char* constructor on any compiler except for clang, and that worked up to 14 characters. There seems to be some promise if you make a bunch of bitsets initialized from unsigned long long and shift and combine them together:

static const std::bitset<128> high(0b0110011001100110011001100110011001100110011001100110011001100110);
static const std::bitset<128> low (0b1001100110011001100110011001100110011001100110011001100110011001);
static const std::bitset<128> set3 = (high << high.size()/2) | low;
std::cout << set3 << '\n';

This makes compilers to stick to binary data storage. If could use a bit newer compiler with constexpr I think it would be possible to declare it as an array of bitsets constructed from ulls and have them concatenated by a constexpr function and bound to a constexpr const variable, which should ensure best optimization possible. Compiler still could go against you, but there would be no reason. Maybe even without constexpr it would generate pretty much optimal code.

Bitset limitation, how to initialize integer at run-time in C++?

a std::bitset's size must be set at compile time as it is a template parameter. If you need a dynamic bitset you can look at boost:dynamic_bitset

Variable size bitset

The std::bitset<N> template requires a fixed size in advance. The std::vector<bool> is the C++ standard's way of providing a variable-length bitvector, and it offers functionality similar to a bitset that can grow and shrink.

As for whether it's better or worse to use vector<char> or vector<bool>: the vector<bool> is a much more direct way of accomplishing this goal. I would start off by using it, then switch to vector<char> if the performance is unacceptable. In general, it's good to try to write the cleanest, most straightforward implementation first, then to optimize later on.

Hope this helps!

Randomly initialize BitSet with specific length

In case I understand it correctly, how do I force it to have 20 random bits always?

Change your for-loops to:

for (int i = 0; i < 20; i++) {
set1.set(i, r.nextBoolean());
set2.set(i, r.nextBoolean());
}

...

for (int i = 0; i < 20; i++) {
s.append(temp1.get(i) == true ? 1 : 0);
}

A BitSet is backed by a long[] and all bits are initially set to false, so calling BitSet#length will not return the value 20 unless the 19th bit happens to be set, as stated by its documentation:

Returns the "logical size" of this BitSet: the index of the highest set bit in the BitSet plus one. Returns zero if the BitSet contains no set bits.

By using the value 20 as the condition in your for-loops, you're ensuring that the first 20 bits will have the opportunity of being set randomly.

Why does std::bitset only takes constexpr value?

Why does N has to be constexpr value?

You are right. Size of both std::bitset and std::array is specified as a template parameter, so it cannot be set during runtime.

However, in the past there were some proposals for introducing dynamic arrays in the C++ standard. One of them was called std::dynarray. Eventually, it won't be introduced into standard but you can see here a more elaborative description of its lifetime.

Is there any 'Hacks' that lets me create variable-length bitset?

If you have access to the Boost library, you can use its dynamic_bitset.



Related Topics



Leave a reply



Submit