Browse Source

Added bbLongPow().

woollybah 6 years ago
parent
commit
22c23d3ab7
2 changed files with 78 additions and 0 deletions
  1. 76 0
      blitz.mod/blitz_cclib.c
  2. 2 0
      blitz.mod/blitz_cclib.h

+ 76 - 0
blitz.mod/blitz_cclib.c

@@ -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;
+    }
+}

+ 2 - 0
blitz.mod/blitz_cclib.h

@@ -74,6 +74,8 @@ BBULONG bbULongMax( BBULONG x, BBULONG y );
 BBULONG bbULongSgn( BBULONG x );
 BBULONG bbULongAbs( BBULONG x );
 
+BBLONG bbLongPow(BBLONG base, BBBYTE exp);
+
 #ifdef __cplusplus
 }
 #endif