Skip to content

Instantly share code, notes, and snippets.

@artemgurzhii
Last active November 23, 2016 12:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save artemgurzhii/b9660f212ae1a56deecbf9c8f18f717a to your computer and use it in GitHub Desktop.
Save artemgurzhii/b9660f212ae1a56deecbf9c8f18f717a to your computer and use it in GitHub Desktop.
Recreation of native CLang log() and pow() functions which works with decimals.
#include <stdio.h>
#include <math.h>
#define MYLOG_N 12
#define MTPOW_N 30
#define EXP_VAL 2.718281828459045090795598298427648842334747314453125
double cfrac_log(double x, unsigned int n) {
if (x < 0) {
return NAN;
}
if (x == 0) {
return -INFINITY;
}
double z = (x - 1.0) / (x + 1.0);
double result = 0.0;
unsigned int i;
for (i = n; i > 0; i--) {
result = (i * i * z * z) / ((i * 2.0 + 1.0) - result);
}
return 2.0 * z / (1.0 - result);
}
double logarithm(double x) {
if (x < 0.0 || isnan(x)) return NAN;
if (x == 0.0) return -INFINITY;
if (isinf(x)) return INFINITY;
int intResult = 0;
if (x >= 1.0) {
while (x >= EXP_VAL) {
x /= EXP_VAL;
intResult++;
}
return cfrac_log(x, MYLOG_N) + intResult;
} else {
while (x < 1.0) {
x *= EXP_VAL;
intResult++;
}
return cfrac_log(x, MYLOG_N) - intResult;
}
}
double power(double x, double y) {
if (isnan(x) || isnan(y)) return NAN;
if (x < 0) return -NAN;
if (isinf(x) || isinf(y)) return INFINITY;
int isPositiveY = y > 0;
if (!isPositiveY) {
y = -y;
}
int integerY = (int) y;
double result1 = 1.0;
double x1 = x;
while (integerY) {
if (integerY & 1) {
result1 *= x1;
}
integerY >>= 1;
x1 *= x1;
}
double result2 = 1.0;
double numerator = (y - (int)y) * (x);
double currentValue = 1.0;
for (unsigned int i = 1; i <= MTPOW_N; i++) {
result2 += (currentValue *= numerator / i);
}
return isPositiveY ? result1 * result2 : 1 / (result1 * result2);
}
int main() {
double numb = 79000000;
printf("Power: Native - %.7e, written - %.7e\n", pow(numb, numb), power(numb, numb));
printf("Log: Native - %.7e, written - %.7e\n", log(numb), logarithm(numb));
return 0;
}
// RESULTS
// Test are only shown for first 7 digits returned by function call
// 'power' and 'logarithm' functions returns same values as native for all numbers
// NOTE: values returned under are same for first 7 digits after dot. Real diffrence is may be bigger
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment