/* ulpow -- BASE_TYPE exponentiation (no overflow detection) * * Based on lpow() code distributed by Doug Gwyn */ #include "hexcalc.h" /* contains BASE_TYPE typedef */ BASE_TYPE ulpow(base, exponent) /* returns base^exponent */ BASE_TYPE base; BASE_TYPE exponent; { BASE_TYPE result; /* result accumulator */ /* handle simple special cases separately: */ if (exponent == 0) { return 1; /* includes 0^0 */ } else if (base == 0) { return 0; /* exp. < 0 should be EDOM */ } else if (base == 1) { return 1; } else if (base == -1) { #if 0 /* intended code: */ return exponent % 2 == 0 ? 1 : -1; #else /* faster equivalent (suggested by Dan Levy of Teletype): */ return (exponent & 1) == 0 ? 1 : -1; #endif } else if (exponent < 0) { return 0; } /* general case with exponent > 0: */ result = 1; for ( ; ; ) /* LOOP INVARIANT: result*base^exponent */ { #if 0 /* intended code: */ if (exponent % 2 != 0) #else /* faster equivalent (suggested by Dan Levy of Teletype): */ if ((exponent & 1) != 0) #endif { result *= base; } #if 0 /* intended code: */ if ((exponent /= 2) == 0) #else /* faster equivalent (suggested by Dan Levy of Teletype): */ if ((exponent >>= 1) == 0) #endif { break; /* result now stable */ } base *= base; } return result; }