Last active
December 6, 2023 01:11
-
-
Save assyrianic/13ccf52e3e3723173801c4793eb8f9c1 to your computer and use it in GitHub Desktop.
integer-based power function
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <limits.h> | |
#include <time.h> | |
#include <math.h> | |
ssize_t ipow(ssize_t const x, size_t n) { | |
ssize_t r = 1; | |
while( n > 0 ) { | |
if( n & 1 ) { | |
r *= x; | |
n--; | |
} else { | |
r *= x * x; | |
n -= 2; | |
} | |
} | |
return r; | |
} | |
ssize_t eluc_pow(ssize_t n, ssize_t p); | |
ssize_t fast_ipow(ssize_t x, ssize_t expo) { | |
if( expo < 0 ) { | |
return 0; | |
} else if( expo==0 || x==1 ) { | |
return 1; | |
} else if( expo >= 64 ) { | |
return 0x7fFFffFFFFffFFffL; | |
} | |
ssize_t b = 1; | |
ssize_t acc = 1; | |
while (b <= expo) { | |
acc *= x * (expo & b); | |
x *= x; | |
b <<= 1; | |
} | |
return acc; | |
} | |
ssize_t eluc_pow(ssize_t n, ssize_t p) { | |
if (p < 0) return 0; // Fractions are rounded to 0 | |
ssize_t b = 1; | |
ssize_t acc = 1; | |
while (b <= p) { | |
acc *= n * (p & b); | |
n *= n; | |
b <<= 1; | |
} | |
return acc; | |
} | |
int main() { | |
ssize_t x = 0*4294967296, expo = 0*2; | |
scanf("%zi", &x); | |
scanf("%zi", &expo); | |
printf("%zi**%zi\n", x, expo); | |
clock_t start = clock(); | |
ssize_t res = 0; | |
enum{ run_counter = 10000000 }; | |
for( size_t i=0 ; i < run_counter; i++ ) { | |
res = fast_ipow(x, expo); | |
} | |
clock_t end = clock(); | |
long double elapsed = ( long double )(end - start) / ( long double )(CLOCKS_PER_SEC); | |
printf("fast_ipow :: elapsed ms: %Lf\n", elapsed * 1000); | |
start = clock(); | |
for( size_t i=0 ; i < run_counter; i++ ) { | |
res = ipow(x, expo); | |
} | |
end = clock(); | |
elapsed = ( long double )(end - start) / ( long double )(CLOCKS_PER_SEC); | |
printf("ipow :: elapsed ms: %Lf\n", elapsed * 1000); | |
start = clock(); | |
for( size_t i=0 ; i < run_counter; i++ ) { | |
res = eluc_pow(x, expo); | |
} | |
end = clock(); | |
elapsed = ( long double )(end - start) / ( long double )(CLOCKS_PER_SEC); | |
printf("eluc_pow :: elapsed ms: %Lf\n", elapsed * 1000); | |
start = clock(); | |
for( size_t i=0 ; i < run_counter; i++ ) { | |
res = pow(x, expo); | |
} | |
end = clock(); | |
elapsed = ( long double )(end - start) / ( long double )(CLOCKS_PER_SEC); | |
printf("pow :: elapsed ms: %Lf\n", elapsed * 1000); | |
start = clock(); | |
for( size_t i=0 ; i < run_counter; i++ ) { | |
res = powf(x, expo); | |
} | |
end = clock(); | |
elapsed = ( long double )(end - start) / ( long double )(CLOCKS_PER_SEC); | |
printf("powf :: elapsed ms: %Lf\n", elapsed * 1000); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment