Concepts / Working with Bitsets

Working with Bitsets

The bitset output operator, used as cout << b, prints the binary representation of a bitset object.

  • Programming

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.

python
Notes on the code
  • 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?

  • It prints 5

  • It prints a string of 0 and 1 characters ending in 101

Reveal answer
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.

bit slot 70bit slot 60bit slot 50bit slot 40bit slot 30bit slot 21bit slot 10bit slot 01
When bitset<8> holds the value 5, how many bit slots exist, and which of them are filled with 0s?

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.

bit 7leftmost characterbit 60bit 50bit 40bit 30bit 21bit 10bit 0rightmost character
In the printed string, which character is bit 0, and which is bit 7? Why does the rightmost character hold the lowest-order bit?

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.

int iholds 5bitset<8> b8 bit positionscout << bbinary representation00000101printed outputcopied into bitssent to output streamprints bits
What steps convert the integer i into the bitset b, and how does the value reach the output stream?
Worked example

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?

  1. 1
    Write 19 in binary

    19 is 10011 in binary, which needs five bit positions.

  2. 2
    Compare with the width

    The bitset has only four positions, so one high-order bit has no slot.

  3. 3
    Keep the low-order bits

    The four rightmost bits, 0011, are the ones that fit into the bitset.

  4. 4
    Print the bitset

    The output operator prints the four stored bits as a fixed-width string.

Result

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 like

    cout << b for a bitset holding 5 prints 00000101, not 5.

    Why it fails

    The bitset output operator prints the binary representation of the bitset object, which is a string of 0 and 1 bits.

    Do this instead

    Read 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 like

    A learner expects 101 but sees 00000101 printed for bitset<8>.

    Why it fails

    The printed output is fixed-width, so every bit position is printed, including the ones holding 0.

    Do this instead

    Count 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 like

    bitset<8 * sizeof(int)> b = i; prints 8 characters only on a machine where int is 1 byte.

    Why it fails

    The template argument multiplies 8 by the number of bytes in an int on the machine, so the width changes with that size.

    Do this instead

    Check 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 like
    bitset<4> b = 19; prints 0011, not 10011.
    Why it fails

    A bitset has a fixed number of positions, so bits beyond that width do not appear in the stored pattern.

    Do this instead

    Choose 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

FeaturePrinting an int with coutPrinting a bitset with cout << b
Output for the value 5500000101 for bitset<8>
Number base shownDecimalBinary, made of 0 and 1 characters
Leading zerosNever printedPrinted, because the width is fixed
WidthDepends on the number of digitsFixed by the template argument

The same value printed two ways

Checking Your Reading of a Bit Pattern

MEDIUM

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.

Related concepts

More concepts starting with W