
/* be sure to use a 32-bit type here */
typedef unsigned long  U32;

/* compute (b^e) % (2^32) */
U32 ipow2(unsigned b, unsigned e) 
{
  U32 r;
  if (e > 1) {
    U32 s = ipow2(b, e/2);
    if (e % 2)                /* odd exponent */
      return s*s*b;
    else
      return s*s;
  } else if (e == 1) {
    return (U32) b;
  } else {
    return 1UL;
  }
}

/* compute (b^e) % (2^32) */
U32 ipow(unsigned b, unsigned e) 
{
  U32 r = 1UL, t;
  for (t = 1<<31; t; t>>=1) {
    r *= r;
    if (e & t) r *= b;
  }
  return r;
}


int main(void)
{
  unsigned i,j;
  /* tests */
  for (i=2; i<6; i++)
    for (j=2; j<6; j++)
      printf("%u^%u = %lu\n", i, j, ipow(i, j));

  printf("5^555 = %lu\n", ipow(5, 555));

  return 0;
}
