I'm writing an implementation of a couple of methods to find the natural logs of numbers using GMP in C. I have two functions, both of which work, but one of which runs a lot slower than the other. The issue is that it is the one that I expected to be faster that is the slowest.
Below are the two relevant functions, while the full file with int main
can be found here, while the required ln_2.txt
file is here.
void taylor_log(mpf_t R,
const mpf_t N,
const mpf_t T)
{
mpf_t x, y, r, pr, tmp, d;
int n = 1;
mpf_init(x);
mpf_init(y);
mpf_init(tmp);
mpf_init(d);
mpf_sub_ui(x, N, 1);
mpf_init_set(y, x);
mpf_init_set(r, x);
mpf_init_set_ui(pr, 0);
mpf_sub(d, r, pr);
mpf_abs(d, d);
while(mpf_cmp(d, T) > 0)
{
mpf_set(pr, r);
mpf_mul(y, y, x);
mpf_div_ui(tmp, y, ++n);
mpf_sub(r, r, tmp);
mpf_mul(y, y, x);
mpf_div_ui(tmp, y, ++n);
mpf_add(r, r, tmp);
mpf_sub(d, r, pr);
mpf_abs(d,d);
}
printf("%d\n", n);
mpf_set(R, r);
}
void hyperbolic_log(mpf_t R,
const mpf_t N,
const mpf_t T)
{
mpf_t x, x2, r, pr, tmp, d;
int n = 1;
mpf_init(x);
mpf_init(x2);
mpf_init(tmp);
mpf_init(d);
mpf_sub_ui(x, N, 1);
mpf_add_ui(tmp, N, 1);
mpf_div(x, x, tmp);
mpf_init_set(r, x);
mpf_init_set_ui(pr, 0);
mpf_mul(x2, x, x);
mpf_sub(d, r, pr);
mpf_abs(d,d);
while(mpf_cmp(d, T) > 0)
{
mpf_set(pr, r);
++n;
mpf_mul(x, x, x2);
mpf_div_ui(tmp, x, ++n);
mpf_add(r, r, tmp);
mpf_sub(d, r, pr);
mpf_abs(d,d);
}
printf("%d\n", n);
mpf_mul_ui(R, r, 2);
}
Now the second function should, in theory at least, run quicker as it has fewer instructions per loop and typically executes fewer loops due to a quicker convergence. This is not what I see in practice, as when I calculated ln(2) to 10000 decimal places using at least 33296 bits in the calculations, both gave the correct result but the first method completed in about 0.150s seconds while the second takes about 1 second.
I have no idea what is causing one function to run so much slower than the other, and any help would be appreciated.
Edit: For clarity I forgot to mention that before being passed to the functions the values are normalized to the range [0.5, 1). This is the same for both functions I've confirmed this works in the program, so technically my issue is when 0.5 is provided to the algorithms.