Based on Mike's answer, but with the numbers correct:
a = 120 values, b = 41 values, c = 10 values
That makes for a total of 49,200 unique values. A byte can only represent 256 values, so you'd need to use at least 16-bits (two bytes) to represent your range.
Now let's suppose we want to use different bits to represent each of these numbers (i.e. no compression that mingles these somehow):
a
fits comfortably in 7 bits, b
fits comfortably in 6 bits, and c
fits comfortably in 4 bits. (By "fits comfortably", I mean that's the smallest integer number of bits this data can fit in.) That's 17 bits, so without applying some kind of compression you might as well use a separate byte for each value.
Now, let's discuss a way to fit this into one character by changing step sizes in these values.
You can divide these up into two 2-bit values (allowing 4 values each) and one 4-bit value. Or you can divide these up into two 3-bit values (allowing 8 values each) and one 2-bit value. You can decide how to assign these to your variables a
, b
, and c
.
The best way to store these in C is with a struct containing bit fields:
struct myvalues{
unsigned a:3;
signed b:3;
unsigned c:2;
};
//look at your compiler and platform documentation
//to make sure you can pack this properly
Then you can access the fields a
, b
, and c
, by name directly (though you'll have to do some math to convert the values.)
Other languages (Java, C#, etc.) aren't so flexible about how you define types, so you'll need to resort to bit shifts in those languages.