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:
- Set an upper bound on the size, use a
bitset
of that size, and just ignore the extra bits. - Switch to an
std::vector<bool>
. This has caveats, but provides roughly similar basic capabilities as abitset
. - 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 bitset
s 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 bitset
s constructed from ull
s 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 19
th 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
Return Statement VS Exit() in Main()
Why Can't I Initialize Non-Const Static Member or Static Array in Class
Is There a Replacement For Unistd.H For Windows (Visual C)
What's the Difference Between Std::Move and Std::Forward
Why Are Arrays of References Illegal
Error "Undefined Reference to 'Std::Cout'"
Why Can't Variable Names Start With Numbers
Create Random Number Sequence With No Repeats
Selectively Disable Gcc Warnings For Only Part of a Translation Unit
Visual C++ Equivalent of Gcc'S _Attribute_ ((_Packed_))
What Is the Windows Equivalent For En_Us.Utf-8 Locale
No Matching Function - Ifstream Open()
How to Check If a Cpu Supports the Sse3 Instruction Set