Concepts / Initializing Bitsets

Initializing Bitsets

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

  • Programming

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.

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

  • The decimal number 5

  • A string of 0 and 1 characters with exactly as many characters as the bitset has bits

  • A string of 0 and 1 characters with only as many characters as the binary form of 5 needs

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

int i = 5decimal valuebinary form 101three bits neededbitset<8> beight fixed positionscout << b00000101binary formcopied into low bits, rest 0printed as string
How do the bits of the integer's binary form flow into the fixed-width bitset, and what happens to the positions the integer does not fill?
Worked example

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?

  1. 1
    Find the width

    The template argument is 8, so the bitset has exactly eight bit positions.

  2. 2
    Write the integer in binary

    The integer 5 is 101 in binary, which is 4 + 1.

  3. 3
    Place the bits

    The three bits 101 occupy the lowest positions. The five higher positions are filled with 0.

  4. 4
    Print the string

    cout << b writes the eight characters 0 and 1 in order, then the newline moves the cursor to a new line.

Result

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.

index 01index 10index 21index 30index 40index 50index 60index 70
Which bit of the integer goes to which index of the bitset, and why does the printed output show the highest index on the left?

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.

StatementPrinted outputWhat it shows
cout << i5The decimal value of the int
cout << b00000101The 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 like

    Printing b for the value 5 and expecting to see 5

    Why it fails

    The bitset output operator prints the binary representation as a string of 0 and 1 characters, not a decimal number.

    Do this instead

    Read the output as a bit pattern, one character per bit.

  • Common mistake

    Expecting no leading zeros in the output

    What it looks like

    Expecting 101 instead of 00000101 for the value 5 in an 8-bit bitset

    Why it fails

    The 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 instead

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

    Expecting a bitset initialized from 5 to print only three characters

    Why it fails

    The width is fixed by the template argument, such as 8 * sizeof(int), not by how many bits the value needs.

    Do this instead

    Determine 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.

300 in binary100101100bitset<8> output00101100high-order bit1 at position 8kept low bitseight positions
If the integer needs more bits than the bitset's size, which high-order bits are dropped and which remain in the printed output?

Trying It Yourself

EASY

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.
MEDIUM

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 when sizeof(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.

Related concepts

More concepts starting with I