Initializing Bitsets
The bitset output operator, used as cout << b, prints the binary representation of a bitset object.
A Short Program to Predict
This article starts with a short function that you can verify by running it. The function takes an ordinary int, copies its value into a bitset, and then sends that bitset to the output stream. Before reading on, try to decide what appears on the screen. The rest of the article uses that prediction to work out why the output looks the way it does.
- bitset<8 *
sizeof(int)> sets the number of bits the bitset holds - b = i copies the integer value into those bits
- cout << b sends the bitset to the output stream as a string of 0 and 1 characters
What do you think happens?
If show(5) is called, what do you think appears on the screen: the decimal 5, or a string of 0 and 1 characters? How many characters do you expect?
Reveal answer
The output is a fixed-width string of 0 and 1 characters, one character per bit, so the printed line has as many characters as the bitset has bits. It is not the decimal 5.
The bitset output operator prints the binary representation the bitset holds, not a decimal value. Because the width is fixed at 8 * sizeof(int), the printed string always has that many characters, including leading zeros.
How the Declaration Sets Up the Bitset
The declaration bitset<8 * sizeof(int)> b = i; does two things at once. The template argument 8 * sizeof(int) fixes how many bits the bitset holds: one bit per position, where 8 is the number of bits in a byte and sizeof(int) is the number of bytes in an int on the machine. The source assumes an 8-bit byte, so on that assumption the width is 8 times the size of an int.
The initializer = i then copies the integer value into those bits. After this line runs, the bitset carries the binary representation of i. The width comes from the template argument, not from how many bits the integer happens to need.
Tracing an Integer Into Bits
Take the value 5 and an 8-bit bitset. The integer 5 has the binary form 101, which uses only three positions. The bitset still has eight positions, so the bits of the integer fill the lowest positions and the remaining positions hold 0.
Printing the Bitset for the Value 5
An int i holds 5. The statement bitset<8> b = i; runs, followed by cout << b << '\n';. What exactly is printed?
- 1Find the width
The template argument is 8, so the bitset has exactly eight bit positions.
- 2Write the integer in binary
The integer 5 is 101 in binary, which is 4 + 1.
- 3Place the bits
The three bits 101 occupy the lowest positions. The five higher positions are filled with 0.
- 4Print the string
cout << b writes the eight characters 0 and 1 in order, then the newline moves the cursor to a new line.
The output line is 00000101, eight characters long.
Reading the Printed Bit Positions
The printed output is a string of 0 and 1 characters, not a decimal value. Each character is one bit of the bitset. To read the output correctly, you need to know which character corresponds to which bit position. In the printed 00000101 from the previous example, the rightmost character is the least significant bit, and the leftmost character is the most significant bit of the eight.
The diagram lists the indices from 7 down to 0 across the printed line, which matches the printed order: the highest index appears first on the left. Index 0 holds the lowest-order bit of the integer, which is the 1 at the right end of 00000101. The value of each bit is read from the integer's binary form, so this mapping is what turns the integer 5 into the printed string.
Comparing Decimal and Bitset Output
Printing the integer and printing the bitset of the same value look completely different. The comparison below uses the value 5 with an 8-bit bitset.
| Statement | Printed output | What it shows |
|---|---|---|
| cout << i | 5 | The decimal value of the int |
| cout << b | 00000101 | The binary representation the bitset holds, with fixed width |
Decimal output versus bitset output for the value 5
Where Printed Patterns Surprise Learners
Common mistake Expecting the printed output to be the decimal value
What it looks likePrinting b for the value 5 and expecting to see 5
Why it failsThe bitset output operator prints the binary representation as a string of 0 and 1 characters, not a decimal number.
Do this insteadRead the output as a bit pattern, one character per bit.
Common mistake Expecting no leading zeros in the output
What it looks likeExpecting 101 instead of 00000101 for the value 5 in an 8-bit bitset
Why it failsThe printed string always has exactly as many characters as the bitset has bits, so leading zeros appear whenever the value needs fewer bits than the width.
Do this insteadCount the characters against the template width. The leading zeros are part of the fixed-width output.
Common mistake Assuming the width depends on the value
What it looks likeExpecting a bitset initialized from 5 to print only three characters
Why it failsThe width is fixed by the template argument, such as 8 *
sizeof(int), not by how many bits the value needs.Do this insteadDetermine the width from the template argument first, then fill the value's bits into that width.
Common mistake Forgetting that the source assumes an 8-bit byte when computing 8 * sizeof(int)
When the Integer Needs More Bits
A bitset has a fixed number of positions, so an integer that needs more bits than the bitset can hold cannot be stored in full. Consider the value 300 copied into an 8-bit bitset. In binary, 300 is 100101100, which needs nine positions. The bitset has only eight, so the high-order bit cannot be kept. The eight low-order bits 00101100 are the part that fits, and the output shows only those.
Trying It Yourself
Without running the code, predict the exact output of the following: a bitset of width 8 is initialized from the int value 6, then printed with cout << b << '\n';. Write out all eight characters, including the leading zeros, and then check your answer by working out the binary form of 6.
Hints
- The binary form of 6 uses three positions: 4 + 2 = 6.
- Fill the three bits into the lowest positions of the eight-character output and pad the rest with 0.
Change the width so the bitset is 8 * sizeof(int) bits and initialize it from the int value 5. How many characters does the printed line have on a machine where sizeof(int) is 4? Explain how the leading zeros in the output follow from the fixed width.
Hints
- On an 8-bit byte machine, 8 *
sizeof(int)equals 32 whensizeof(int)is 4. - The printed string has one character per bit, so count the bits, not the digits of the value.
Key Takeaways
- The statement bitset<8 *
sizeof(int)> b = i; fixes the bitset width with the template argument and copies the integer's bits into it. - cout << b prints the binary representation as a fixed-width string of 0 and 1 characters, not a decimal value.
- Leading zeros appear in the output because the printed string always has as many characters as the bitset has bits.
- An integer that needs more bits than the bitset holds loses its high-order bits, and only the bits that fit appear in the output.