View Single Post
Old 05-06-2007, 10:51 PM   #7 (permalink)
teknomage1
Jack of all trades
 
teknomage1's Avatar
 
Join Date: Feb 2005
Location: Los Angeles
Posts: 598
teknomage1 is on a distinguished road
Send a message via AIM to teknomage1
Well the reason the numbers didn't come out was because the built in pow works with floats or doubles, which are too small to hold your number, so you can define a new version of pow that works with unsigned longs which can hold your large numbers.
Code:
unsigned long ulpow( unsigned long base, unsigned int exponent )
{
  unsigned long result = 1;
  while( exponent > 0 ){
    result *= base;
    exponent--;
  }

  return result;
}
That's just a simple translation of the definition of the power function, but it uses the unsigned long so we know it won't overflow with the size of the numbers you need. It's going to be marginally slower than the standard pow, and it doesn't handle as many cases (like fractional exponents or negative exponents). Since your exponent is (i/7), we can't guarantee that's going to be integral so we should modify it a to be a bit more accurate.
Code:
unsigned long ulpow( unsigned long base, unsigned long double exponent )
{
  unsigned long result = 1;
  unsigned int integralExp = exponent;
  long double fractionalExp = exponent - (long double)integralExp;
  if( fractionalExp ){
    /* This is still bad since the inexactness here will add up to a lot later*/
    result = powl((long double)base,fractionalExp);
  }
  while( exponent > 0 ){
    result *= base;
    exponent--;
  }

  return result;
}
It's still going to be wrong because it drops significant figures, for example:
pow(2.0,2.5) = 5.565
ulpow(2,2.5) = 4
But for integral values of (i/7) it will be correct, and it should be more correct on large values than the overflowed version. Perhaps smarter rounding might help. I guess it depends on how accurate you need to be.
__________________
Stop intellectual property from infringing on me
teknomage1 is offline   Reply With Quote