#include <iostream>
using namespace std;
class Student
{
private:
// packing student info in 2 bytes:
//
// 15 13 8 7 3 2 10 <- bit positions
// xx gggggg ccccc m yy
//
// Year in bits 0..1: 2 bits for 4 options (00, 01, 10, 11: need to adjust +1)
// Major in bit 2: 1 bits for 2 options (T/F)
// Credits in bits 3..6: 5 bits for 32 options (0..31: need to adjust +1)
// GPA in bits 8..13: 6 bits for 44 options (0..43)
//
// bits 14 and 15 are not used
unsigned short data;
public:
Student() : data(0)
{
}
Student( int year, int credits ) : data(0)
{
setYear( year );
setCredits( credits );
}
int getYear()
{
unsigned short mask = 0x0003; // or 0b0000.0000.0000.0011
unsigned short year = data & mask; // extract only last two bits, rest are 0
return year + 1; // convert 0,1,2,3 back to 1,2,3,4
}
int getCredits()
{
unsigned short mask = 0x001F; // or 0b0000.0000.0001.1111 (5 bits)
mask = mask << 3; // 0000.0000.1111.1000
// move by 3 to position under bits 3..7
unsigned short credits = data & mask; // sample data: 0000101101101010 &
// mask: ........11111000 <- . for 0, less clutter
// credits: 0000000001101000 = 13*2^3
credits = credits >> 3; // credits: 0000000000001101 = 13
// move by 3 to position to beginning
credits--; // adjust credits
return credits;
}
void setYear( int year )
{
unsigned short mask = 0x0003; // or 0b0000.0000.0000.0011
// sample data: 0000101101101001 & <- "multiply"
data = data & ~mask; // ~mask: 1111111111111100 <- "1 keep, 0 clear
// data: 0000101101101000
year = year - 1; // convert 1,2,3,4, i.e. 01, 10, 11, 100
// into 0,1,2,3, i.e. 00, 01, 10, 11
data = data | year; // data: 0000101101101000 |
// year: ..............10 <- . for 0, less clutter
// data: 0000101101101010
}
void setCredits( int credits )
{
unsigned short mask = 0x001F; // or 0b0000.0000.0001.1111 (5 bits)
mask = mask << 3; // move by 3 to position under bits 3..7
// 0b0000.0000.1111.1000
mask = ~mask; // flip 0b1111.1111.0000.0111
// so desired 5 bits cleared, rest kept, when "multiply" with &
// sample data: 0000101101101001 & <- "multiply"
data = data & mask; // mask: 1111111100000111
// data: 00001011.....001 & <- . for 0
credits++; // adjust credits
credits = credits << 3; // move by 3 to position under bits 3..7
// new credits: ........10110...
data = data | credits; // data: 00001011 ..... 001 | <- add with 0s to keep rest
// credits: ........ 10110 ... <- . for 0
// data: 00001011 10110 001
}
void print()
{
cout << "Student details:" << endl
<< "- year : " << getYear() << endl
<< "- credits: " << getCredits() << endl;
// << "- major : " << getMajor() << endl
// << "- gpa : " << getGPA() << endl;
}
};
int main()
{
Student s1; // calls default c-tor
Student s2( 1, 25 ); // calls 2nd c-tor
s1.print();
s2.print();
s1.setYear(2);
cout << s1.getYear() << endl;
s1.setCredits(17);
cout << s1.getCredits() << endl;
s1.print();
s1.setYear(3);
cout << s1.getYear() << endl;
s1.setCredits(23);
cout << s1.getCredits() << endl;
s1.print();
}