Working with Bitsets
The bitset output operator, used as cout << b, prints the binary representation of a bitset object.
Predicting the First Output
This article begins with a short program that you can verify by running it. It takes an ordinary int, copies its value into a bitset, and then sends that bitset to the output stream. Before you read the explanation, try to predict what appears on the screen. The goal is to work out why the output looks the way it does, not just to memorize what it prints.
- int i = 5; creates an ordinary integer holding the value five
- bitset<8 *
sizeof(int)> b = i; creates a bitset whose width depends on the size of int, then copies i into it - std::cout << b << '\n'; prints the bits and moves to a new line
What do you think happens?
The program stores the value 5 in a bitset and prints it. Does the output look like the number 5, or like a string of 0 and 1 characters?
Reveal answer
It prints a string of 0 and 1 characters ending in 101. On a machine where int is 4 bytes, the bitset is 32 bits wide, so the output is 32 characters: 00000000000000000000000000000101.
The bitset output operator prints the binary representation of the bitset, not a decimal value. The width comes from 8 * sizeof(int), so the number of characters depends on how many bytes an int occupies on the machine.
How the Declaration Fixes the Width
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. Here 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 the bit width is the byte count multiplied by 8.
The initializer = i then copies the integer value into those bit positions. After this step the bitset carries the binary representation of i. Because the width is fixed at declaration time, the bitset always has the same number of positions, whatever the value stored in it.
The diagram shows eight slots for bitset<8>. The value 5 has binary form 101, so only the two slots for 4 and 1 are set to 1. The remaining slots are filled with 0s, which is why the printed string has leading zeros.
Reading the Printed Characters
The printed output is a fixed-width string of 0 and 1 characters. Each character corresponds to one bit position. The rightmost character is the lowest-order bit, which is bit 0. The leftmost character is the highest-order bit, which is bit size minus 1. Reading the string from left to right moves from the highest position down to position 0.
For the value 5, the printed string is 00000101. Bit 0 is the rightmost character and holds 1. Bit 2 is the third character from the right and also holds 1. Every other position holds 0. The rightmost position is the lowest-order bit because it contributes the smallest place value to the number, just as the rightmost digit of a decimal number is its ones digit.
Following a Value From int to Output
Trace the steps that carry the value from the integer into the printed output. Each step only moves or displays the stored bits; no step converts the value into decimal.
What happens when the value does not fit the width
A program declares bitset<4> b = 19; and then runs cout << b << '\n';. What is printed?
- 1Write 19 in binary
19 is 10011 in binary, which needs five bit positions.
- 2Compare with the width
The bitset has only four positions, so one high-order bit has no slot.
- 3Keep the low-order bits
The four rightmost bits, 0011, are the ones that fit into the bitset.
- 4Print the bitset
The output operator prints the four stored bits as a fixed-width string.
The program prints 0011. The value 19 is not shown in full because the declared width is only 4 bits.
Where Printed Bits Surprise Learners
Common mistake Expecting cout << b to print a decimal number
What it looks likecout << b for a bitset holding 5 prints 00000101, not 5.
Why it failsThe bitset output operator prints the binary representation of the bitset object, which is a string of 0 and 1 bits.
Do this insteadRead the output as a bit pattern. Convert it to decimal yourself if you need the number.
Common mistake Expecting no leading zeros
What it looks likeA learner expects 101 but sees 00000101 printed for bitset<8>.
Why it failsThe printed output is fixed-width, so every bit position is printed, including the ones holding 0.
Do this insteadCount the characters. The number of characters equals the bitset width, which comes from 8 * sizeof(int) in the source declaration.
Common mistake Assuming the width is always 8
What it looks likebitset<8 * sizeof(int)> b = i; prints 8 characters only on a machine where int is 1 byte.
Why it failsThe template argument multiplies 8 by the number of bytes in an int on the machine, so the width changes with that size.
Do this insteadCheck sizeof(int) on your machine, or use an explicit width when the number of bits matters.
Common mistake Assuming a value always fits the declared width
What it looks likebitset<4> b = 19; prints 0011, not 10011.Why it failsA bitset has a fixed number of positions, so bits beyond that width do not appear in the stored pattern.
Do this insteadChoose a width large enough for the largest value you store.
Common mistake Reading the leftmost character as bit 0 instead of the highest-order bit
| Feature | Printing an int with cout | Printing a bitset with cout << b |
|---|---|---|
| Output for the value 5 | 5 | 00000101 for bitset<8> |
| Number base shown | Decimal | Binary, made of 0 and 1 characters |
| Leading zeros | Never printed | Printed, because the width is fixed |
| Width | Depends on the number of digits | Fixed by the template argument |
The same value printed two ways
Checking Your Reading of a Bit Pattern
A program declares bitset<6> b = 10; and runs cout << b << '\n';. Predict the printed output before you check it. Then identify which bit positions hold 1.
Hints
- Write 10 in binary first. It is 1010.
- The bitset has six positions, so pad the left side with 0s until the string has six characters.
- Bit 0 is the rightmost character. Count from the right to find bits 1 and 3.
Key Takeaways
- The bitset output operator, used as cout << b, prints the binary representation of a bitset object as a fixed-width string of 0 and 1 characters, not as a decimal value.
- The declaration bitset<8 *
sizeof(int)> b = i; sets the width to 8 times the number of bytes in an int, and the initializer copies the bits of i into those positions. - The rightmost printed character is bit 0, the lowest-order bit, and the leftmost is bit size minus 1.
- Printed bitset output includes leading zeros, and a value wider than the declared size does not appear in full, so the printed pattern can differ from what a learner expects.