|
@@ -155,3 +155,79 @@ BBULONG bbULongMin( BBULONG x,BBULONG y ){
|
|
|
BBULONG bbULongMax( BBULONG x,BBULONG y ){
|
|
|
return x>y ? x : y;
|
|
|
}
|
|
|
+
|
|
|
+BBLONG bbLongPow(BBLONG base, BBBYTE exp) {
|
|
|
+ static const BBBYTE highest_bit_set[] = {
|
|
|
+ 0, 1, 2, 2, 3, 3, 3, 3,
|
|
|
+ 4, 4, 4, 4, 4, 4, 4, 4,
|
|
|
+ 5, 5, 5, 5, 5, 5, 5, 5,
|
|
|
+ 5, 5, 5, 5, 5, 5, 5, 5,
|
|
|
+ 6, 6, 6, 6, 6, 6, 6, 6,
|
|
|
+ 6, 6, 6, 6, 6, 6, 6, 6,
|
|
|
+ 6, 6, 6, 6, 6, 6, 6, 6,
|
|
|
+ 6, 6, 6, 6, 6, 6, 6, 255, // anything past 63 is a guaranteed overflow with base > 1
|
|
|
+ 255, 255, 255, 255, 255, 255, 255, 255,
|
|
|
+ 255, 255, 255, 255, 255, 255, 255, 255,
|
|
|
+ 255, 255, 255, 255, 255, 255, 255, 255,
|
|
|
+ 255, 255, 255, 255, 255, 255, 255, 255,
|
|
|
+ 255, 255, 255, 255, 255, 255, 255, 255,
|
|
|
+ 255, 255, 255, 255, 255, 255, 255, 255,
|
|
|
+ 255, 255, 255, 255, 255, 255, 255, 255,
|
|
|
+ 255, 255, 255, 255, 255, 255, 255, 255,
|
|
|
+ 255, 255, 255, 255, 255, 255, 255, 255,
|
|
|
+ 255, 255, 255, 255, 255, 255, 255, 255,
|
|
|
+ 255, 255, 255, 255, 255, 255, 255, 255,
|
|
|
+ 255, 255, 255, 255, 255, 255, 255, 255,
|
|
|
+ 255, 255, 255, 255, 255, 255, 255, 255,
|
|
|
+ 255, 255, 255, 255, 255, 255, 255, 255,
|
|
|
+ 255, 255, 255, 255, 255, 255, 255, 255,
|
|
|
+ 255, 255, 255, 255, 255, 255, 255, 255,
|
|
|
+ 255, 255, 255, 255, 255, 255, 255, 255,
|
|
|
+ 255, 255, 255, 255, 255, 255, 255, 255,
|
|
|
+ 255, 255, 255, 255, 255, 255, 255, 255,
|
|
|
+ 255, 255, 255, 255, 255, 255, 255, 255,
|
|
|
+ 255, 255, 255, 255, 255, 255, 255, 255,
|
|
|
+ 255, 255, 255, 255, 255, 255, 255, 255,
|
|
|
+ 255, 255, 255, 255, 255, 255, 255, 255,
|
|
|
+ 255, 255, 255, 255, 255, 255, 255, 255,
|
|
|
+ };
|
|
|
+
|
|
|
+ BBLONG result = 1;
|
|
|
+
|
|
|
+ switch (highest_bit_set[exp]) {
|
|
|
+ case 255: // we use 255 as an overflow marker and return 0 on overflow/underflow
|
|
|
+ if (base == 1) {
|
|
|
+ return 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (base == -1) {
|
|
|
+ return 1 - 2 * (exp & 1);
|
|
|
+ }
|
|
|
+
|
|
|
+ return 0;
|
|
|
+ case 6:
|
|
|
+ if (exp & 1) result *= base;
|
|
|
+ exp >>= 1;
|
|
|
+ base *= base;
|
|
|
+ case 5:
|
|
|
+ if (exp & 1) result *= base;
|
|
|
+ exp >>= 1;
|
|
|
+ base *= base;
|
|
|
+ case 4:
|
|
|
+ if (exp & 1) result *= base;
|
|
|
+ exp >>= 1;
|
|
|
+ base *= base;
|
|
|
+ case 3:
|
|
|
+ if (exp & 1) result *= base;
|
|
|
+ exp >>= 1;
|
|
|
+ base *= base;
|
|
|
+ case 2:
|
|
|
+ if (exp & 1) result *= base;
|
|
|
+ exp >>= 1;
|
|
|
+ base *= base;
|
|
|
+ case 1:
|
|
|
+ if (exp & 1) result *= base;
|
|
|
+ default:
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+}
|