I've been given the following assignment in a C-course:
I've implemented the assignment to decode the 8 byte long long int 131809282883593 as follows:
#include <stdio.h>
#include <string.h>
struct Message {
unsigned int hour : 5;
unsigned int minutes : 6;
unsigned int seconds : 6;
unsigned int day : 5;
unsigned int month : 4;
unsigned int year : 12;
unsigned long long int code : 26;
}; // 64 bit in total
union Msgdecode {
long long int datablob;
struct Message elems;
};
int main(void) {
long long int datablob = 131809282883593;
union Msgdecode m;
m.datablob = datablob;
printf("%d:%d:%d %d.%d.%d code:%lu\n", m.elems.hour, m.elems.minutes,
m.elems.seconds, m.elems.day, m.elems.month, m.elems.year,(long unsigned int) m.elems.code);
union Msgdecode m2;
m2.elems.hour = 9;
m2.elems.minutes = 0;
m2.elems.seconds = 0;
m2.elems.day = 30;
m2.elems.month = 5;
m2.elems.year = 2017;
m2.elems.code = 4195376;
printf("m2.datablob: should: 131809282883593 is: %lld\n", m2.datablob); //WHY does m2.datablob != m.datablob?!
printf("m.datablob: should: 131809282883593 is: %lld\n", m.datablob);
printf("%d:%d:%d %d.%d.%d code:%lu\n", m2.elems.hour, m2.elems.minutes,
m2.elems.seconds, m2.elems.day, m2.elems.month, m2.elems.year, (long unsigned int) m2.elems.code);
}
..what gives me a hard time is the output. The decoding/encoding works nicely so far. 9:0:0 30.5.2017 and code 4195376 is expected, but the difference in the 'datablob' really isn't - and i can't figure out why/where it stems from:
9:0:0 30.5.2017 code:4195376
m2.datablob: should: 131809282883593 is: 131810088189961
m.datablob: should: 131809282883593 is: 131809282883593
9:0:0 30.5.2017 code:4195376
As you can see the datablob is close to the original - but not the original. I've consulted a coworker whos fluent in C about this - but we couldn't figure out the reason for this behaviour.
Q: Why do the blobs differ from each other?
Bonus-Q: When manipulating the union Msgdecode to include another field, a strange thing happens:
union Msgdecode {
long long int datablob;
struct Message elems;
char bytes[8]; // added this
};
Outcome:
9:0:0 30.5.2017 code:0
m2.datablob: should: 131809282883593 is: 8662973939721
m.datablob: should: 131809282883593 is: 131809282883593
9:0:0 30.5.2017 code:4195376
PS: reading on SO about bitfields+union questions gave me the impression that they are rather unreliable. Can this be generally said?
