So
here's normal, base1 counting on your fingers. In base 1, you
just raise the number of fingers equal to the value you're trying to
represent:


This is funky base2 counting on your fingers. Each finger represents a
different value now, so you have to start counting with '1' at your
pinky, then '2' with just your ring finger, and '3=2+1' is pinky and
ring finger together. '4' is a single raised middle finger. Then
'5=4+1' is middle finger and pinky, and so on. Just 10 digits actually
allows you to count all the way to 1023, but we'll ignore the thumbs
and just use 8 fingers, to count up to 255=128+64+32+16 (left hand
palmup, pinky is 16) +8+4+2+1 (right hand palmdown, pinky is 1).
This is actually somewhat useful for countingtry it! (Note: the numbers four, sixtyfour, and especially sixtyeight should not be prominently displayed. Digital binary counting is not recommended in a ganginfested area.) 
long x=1024;Why? The real answer is 4 billion (and change), which requires 33 bits: a 1 followed by 32 zero bits. But on a 32bit machine, all you get is the zeros; the higher bits "overflow" and (at least in C/C++) are lost! Understanding the bits underneath your familiar integers can help you understand errors like this one. (Plus, by writing assembly code, you can actually recover the highorder bits after a multiplication if you need them.)
long y=x*x*x*4;
return y;
As Ints 
As Bits 
3<<0 == 3 
0011<<0 == 0011 
3<<1 == 6 
0011<<1 == 0110 
3<<2 == 12 
0011<<2 == 1100 
As Ints 
As Bits 
3>>0 == 3 
0011>>0 == 0011 
3>>1 == 1 
0011>>1 == 0001 
3>>2 == 0 
0011>>2 == 0000 
6>>1 == 3 
0110>>1 == 0011 
As Ints 
As Bits 
3&5 == 1 
0011&0101 == 0001 
3&6 == 2 
0011&0110 == 0010 
3&4 == 0 
0011&0100 == 0000 
As Ints 
As Bits 
30 == 3 
00110000 == 0011 
33 == 3 
00110011 == 0011 
14 == 5 
00010100 == 0101 
As Ints 
As Bits 
3^5 == 6 
0011&0101 == 0110 
3^6 == 5 
0011&0110 == 0101 
3^4 == 7 
0011&0100 == 0111 
As Ints 
As Bits 
~0 == big value 
~...0000 == ...1111 
enum {n=1}; // Number of integers in our tables (== size of internet / 32)The same bitwise testing idea shows up in the "region codes" of CohenSutherland clipping, used in computer graphics.
unsigned int funky_table[n]={(1<<24)(1<<17)(1<<12)(1<<4)};
unsigned int aardvark_table[n]={(1<<31)(1<<24)(1<<15)(1<<6)(1<<4)};
/* Match up the bits of these two tables using bitwise operations */
void both_tables(const unsigned int *a,const unsigned int *b,unsigned int *o) {
for (int i=0;i<n;i++) o[i]=a[i]&b[i]; /* bitwise AND */
}
/* Match up the bits of these two tables using logical (onebit) operations */
void both_tables_logical(const unsigned int *a,const unsigned int *b,unsigned int *o)
{
for (int i=0;i<n;i++) {
o[i]=0;
for (int bit=0;bit<32;bit++)
{
unsigned int a_bit=a[i]&(1<<bit);
unsigned int b_bit=b[i]&(1<<bit);
if (a_bit && b_bit) /* logical AND */
o[i]=o[i](1<<bit);
}
}
}
int foo(void) {
unsigned int output_table[n];
both_tables(funky_table,aardvark_table,output_table);
return output_table[0];
}