Reputation:
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
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
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
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