user466534
user466534

Reputation:

Bitfields in C++

I have the following code for self learning:

#include <iostream>
using namespace std;
struct bitfields{
    unsigned field1: 3;
    unsigned field2: 4;
    unsigned int k:  4;
};

int main(){
    bitfields field;
    field.field1=8;
    field.field2=1e7;
    field.k=18;
    cout<<field.k<<endl;
    cout<<field.field1<<endl;
    cout<<field.field2<<endl;
    return 0;
}

I know that unsigned int k:4 means that k is 4 bits wide, or a maximum value of 15, and the result is the following.

2
0
1

For example, filed1 can be from 0 to 7 (included), field2 and k from 0 to 15. Why such a result? Maybe it should be all zero?

Upvotes: 4

Views: 3019

Answers (3)

Nordic Mainframe
Nordic Mainframe

Reputation: 28767

In C++ any unsigned type wraps around when you hit its ceiling[1]. When you define a bitfield of 4 bits, then every value you store is wrapped around too. The possible values for a bitfield of size 4 are 0-15. If you store '17', then you wrap to '1', for '18' you go one more to '2'.

Mathematically, the wrapped value is the original value modulo the number of possible values for the destination type:

For the bitfield of size 4 (2**4 possible values):

18 % 16 == 2
17 % 16 == 1

For the bitfield of size 3 (2**3 possible values):

8 % 8 == 0.

[1] This is not true for signed types, where it is undefined what happens then.

Upvotes: 1

kbrimington
kbrimington

Reputation: 25692

You have these results because the assignments overflowed each bitfield.

The variable filed1 is 3 bits, but 8 takes 4 bits to present (1000). The lower three bits are all zero, so filed1 is zero.

For filed2, 17 is represented by 10001, but filed2 is only four bits. The lower four bits represent the value 1.

Finally, for k, 18 is represented by 10010, but k is only four bits. The lower four bits represent the value 2.

I hope that helps clear things up.

Upvotes: 4

falstro
falstro

Reputation: 35687

You're overflowing your fields. Let's take k as an example, it's 4 bits wide. It can hold values, as you say, from 0 to 15, in binary representation this is

0  -> 0000
1  -> 0001
2  -> 0010
3  -> 0011
...
14 -> 1110
15 -> 1111

So when you assign 18, having binary representation

18 -> 1 0010 (space added between 4th and 5th bit for clarity)

k can only hold the lower four bits, so

k = 0010 = 2.

The equivalent holds true for the rest of your fields as well.

Upvotes: 9

Related Questions