Skip to content

Instantly share code, notes, and snippets.

@assyrianic
Last active December 6, 2023 01:11
Show Gist options
  • Save assyrianic/13ccf52e3e3723173801c4793eb8f9c1 to your computer and use it in GitHub Desktop.
Save assyrianic/13ccf52e3e3723173801c4793eb8f9c1 to your computer and use it in GitHub Desktop.
integer-based power function
#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