#include "mypow.h"
#include "math.h"



long Log[256]=
{0,
-11348,-9928,-9098,-8508,-8051,-7678,-7362,-7089,-6848,-6632,-6437,-6258,-6094,
-5943,-5801,-5669,-5545,-5428,-5317,-5212,-5112,-5017,-4926,-4839,-4755,-4675,
-4598,-4523,-4451,-4382,-4315,-4250,-4187,-4126,-4066,-4008,-3952,-3898,-3845,
-3793,-3742,-3693,-3645,-3597,-3551,-3506,-3462,-3419,-3377,-3336,-3295,-3255,
-3216,-3178,-3140,-3104,-3067,-3032,-2997,-2962,-2928,-2895,-2862,-2830,-2798,
-2767,-2736,-2706,-2676,-2647,-2618,-2589,-2561,-2533,-2505,-2478,-2451,-2425,
-2399,-2373,-2348,-2323,-2298,-2273,-2249,-2225,-2201,-2178,-2155,-2132,-2109,
-2087,-2065,-2043,-2021,-2000,-1978,-1957,-1937,-1916,-1896,-1876,-1856,-1836,
-1816,-1797,-1778,-1759,-1740,-1721,-1702,-1684,-1666,-1648,-1630,-1612,-1595,
-1577,-1560,-1543,-1526,-1509,-1492,-1476,-1459,-1443,-1427,-1411,-1395,-1379,
-1363,-1348,-1332,-1317,-1302,-1286,-1271,-1256,-1242,-1227,-1212,-1198,-1184,
-1169,-1155,-1141,-1127,-1113,-1099,-1086,-1072,-1059,-1045,-1032,-1019,-1005,
-992,-979,-966,-954,-941,-928,-916,-903,-891,-878,-866,-854,-841,-829,-817,
-805,-794,-782,-770,-758,-747,-735,-724,-712,-701,-690,-678,-667,-656,-645,
-634,-623,-612,-602,-591,-580,-570,-559,-548,-538,-528,-517,-507,-497,-486,
-476,-466,-456,-446,-436,-426,-416,-406,-397,-387,-377,-368,-358,-348,-339,
-329,-320,-311,-301,-292,-283,-274,-264,-255,-246,-237,-228,-219,-210,-201,
-193,-184,-175,-166,-158,-149,-140,-132,-123,-115,-106,-98,-89,-81,-73,-64,
-56,-48,-40,-31,-23,-15,-7,0};

unsigned long mypow(int n,unsigned long x)
{
  long total;
  long xlogn;
  long newfrac,absfrac;
  int count;

  if (n==0) return 0;

  
  if (n==255) return (1L << (2*PowInfBase));
/*
  printf("n %d x %d\n",n,x);
*/
  xlogn=x*Log[n]+(1L << (PowInfBase-1));
  if (xlogn<(long) ((1L << (2*PowInfBase))*(-6.214608)) ) return(0);   /* -6.2 */
  
  total=(1L << (2*PowInfBase))+xlogn;
/*
  printf("xlogn %ld xlogn/2^PowInfBase %ld\n",xlogn,xlogn >> (PowInfBase));
*/  
  newfrac=(xlogn >> (PowInfBase) )*(xlogn >> (PowInfBase) ) >> 1;
/*
  printf("total: %ld\t newfrac %ld %.5lf\n",total,newfrac,((double) total)/(1L << (2*PowInfBase)));
*/
  count=3;
  if (newfrac<0) absfrac=-newfrac; else absfrac=newfrac;
  
  while(absfrac> (long) (0.0001*(1L << (2*PowInfBase))) ) /* 0.0005 */
    {
     total+=newfrac;
/*
  printf("total: %ld\t newfrac %ld %.5lf\n",total,newfrac,((double) total)/(1L << (2*PowInfBase)));
*/
      newfrac=((newfrac + (1L << (PowInfBase-1))) >> (PowInfBase)) *
        ((xlogn/count)>> (PowInfBase));
   if (newfrac<0) absfrac=-newfrac; else absfrac=newfrac;
     count++;
    }


  total+=newfrac;

/*
  printf("total: %ld\t newfrac %ld %.5lf\n",total,newfrac,((double) total)/(1L << (2*PowInfBase)));
*/

  return(total);
}

#ifdef OLD_CODE
main(int argc, char *argv[])
{
  int i,j,k;
  double x,y,z;
  
  int index;            /* LUT index */
  double scale;			/* scale factor (K) */
  double lutVal;        /* LUT value */

/*
  for(i=1;i<256;i++) 
    Log[i]=(int) (log((double)i)*(1L << PowInfBase)+0.5);
*/
/*
  for(i=1;i<256;i++) 
  {
    Log[i]=(long) (log((double)i/255.0)*(1L <<PowInfBase)+0.5);
}
*/
  x=atof(argv[1]);
  y=atof(argv[2]);

  i=mypow((int) x,((ulong) (y * (1L << PowInfBase))));
  
  printf("%.7lf \n",((double) i)/(1L << (PowInfBase*2)));
    printf("%.7lf\n",pow(x/255.0,y));

/*
      for (index = minIn; index <= maxIn; index++)
    {
      lutVal = minOut + scale * pow (index - minIn, gamma);
      *pLut++ = (BYTE) (lutVal + 0.5);
    }
*/

}
#endif
