Don't really know of any specific tutorials but wikipedia has a pretty good explanation on how it works.
Bitwise operation - Wikipedia, the free encyclopedia
And here's a short example
Or you can use preprocessor macros like
// This code assumes an int is 32 bits for simplicity.
// In real code you might want to check sizeof(int)
// and adjust the mask and shift values unless you know
// it will only be run on machines with 32 bit ints.
// Initial values
// These can be read from a file or the command line or whatever :)
int numerator = 13;
int denominator = 45;
// Store the fraction
// First we mask (bitwise AND) with 0xFFFF (16 bits of all 1's, half of a 32-bit int)
// to make sure the inputted numbers aren't bigger than 16 bits.
// Then we shift the numerator 16 bits to the left
// and bitwise OR it with the denominator.
// numerator is now in the upper half of fraction,
// and denominator is in the lower half.
int fraction = ((numerator & 0xFFFF) << 16) | (denominator & 0xFFFF);
// Retrieve the fraction parts
// For n we use a bitmask to get only the upper half,
// and then shift it back 16 bits to the right.
// For d we just grab the lower half directly.
int n = (fraction & 0xFFFF0000) >> 16;
int d = fraction & 0x0000FFFF;
printf("numerator = %d\n", n);
printf("denominator = %d\n", d);
Since we are using 16 bit numbers the maximum range for the numerator and denominator is 0 to 65535. If you want to be able to handle negative numbers you would have to use 1 bit as a sign bit and the range would be -32768 to 32767
#define MAKEFRACTION(num,den) (((num & 0xFFFF)<<16) | (den & 0xFFFF))
#define LOWPART(f) (f & 0xFFFF)
#define HIGHPART(f) ((f>>16)&0xFFFF)
fraction = MAKEFRACTION(numerator,denominator);
numerator = HIGHPART(fraction);
denominator = LOWPART(fraction);
Of course if you used a 64bit data type for the fraction, for example long long, you would get a much bigger range. (0 to 2^32 for unsigned)
Although is it worth all the extra trouble just to avoid using a struct or an array of 2 ints?