-2

Here's the function:

arbFloat catalan(){
    arbFloat output, n = 0, first, second;
    std::string preComp, postComp;
    do{
        preComp = resizeArbtoString(first);
        first += (1.0 / pow(2.0, 4.0 * n)) * (
                (- 1.0 / (2.0 * pow(8.0*n + 2.0, 2.0))) +
                (1.0 / (4.0 * pow(8.0*n + 3.0, 2.0))) +
                (- 1.0 / (8.0 * pow(8.0*n + 5.0, 2.0))) +
                (1.0 / (8.0 * pow(8.0*n + 6.0, 2.0))) +
                (-1.0 / (16.0 * pow(8.0*n + 7.0, 2.0))) +
                (1.0 / (2.0 * pow(8.0*n + 1.0, 2.0)))
                );
        postComp = resizeArbtoString(first);
        n++;
    } while(preComp != postComp);
    n = 0;
    do{
        preComp = resizeArbtoString(second);
        second += (1.0 / pow(2.0 , 12.0 * n)) * (
                (1.0 / (16.0 * pow(8.0*n + 2, 2.0))) +
                (1.0 / (64.0 * pow(8.0*n + 3, 2.0))) +
                (-1.0 / (512.0 * pow(8.0*n + 5, 2.0))) +
                (-1.0 / (1024.0 * pow(8.0*n + 6, 2.0))) +
                (1.0 / (4096.0 * pow(8.0*n + 7, 2.0))) +
                (1.0 / (8.0 * pow(8.0*n + 1, 2.0)))
                );
        postComp = resizeArbtoString(second);
        n++;
    } while(preComp != postComp);

    output = (3.0*first) - (2.0*second);

    return output;
}

This code is meant to calculate the value of Catalan's constant. I am using the method that quickly converges, compared to the slowly-converging equation.

arbFloat is a Boost multi-precision cpp_dec_float with the precision of 100 decimal places:

typedef boost::multiprecision::number<boost::multiprecision::cpp_dec_float<100>> arbFloat

The function resizeArbtoString() simply converts the variable to a string, and resizes it to account for the first decimal and decimal mark. It isn't important here, and I have verified that it does not impact the result.

I get the value of first before and after calculations to stop an infinite loop when the precision is bypassed (same for the variable second). The do-while loop checks this. This is what makes it an iterative method.

The two do-while loops separately get the values of the two summations in the equation (image below). Then the output variable multiplies the first summation by 3, and the second summation by -2, then adds them together.

This function is returning the value of:

0.9159456632705320620288006061761625716626752650763000222738355046579667073981960968090933049341304381

When the value should instead be:

.915965594177219015054603514932384110774149374281672134266498119621763019776254769479356512926115106248574

(correct constant value via OEIS)

Here is the equation that I referenced when creating this function:

Equation for quicker convergence towards Catalans Constant

Why is this returning an imprecise value?

esote
  • 831
  • 12
  • 25
  • 1
    Do not use [pow with integer exponents](http://stackoverflow.com/questions/25678481/why-does-pown-2-return-24-when-n-5-with-my-compiler-and-os). The `pow` function is a floating point function -- there has been several posts where the user is using certain versions of g++ where `pow` will not give exact results when used with integer exponents. – PaulMcKenzie Oct 30 '16 at 05:57

1 Answers1

2

Your 1.0 / 4096.0 term in second should be -1.0 / 4096.0.

1201ProgramAlarm
  • 32,384
  • 7
  • 42
  • 56
  • @Anonymous -- Read my comments in the main section. You have potentially other issues concerning the usage of `pow`. – PaulMcKenzie Oct 30 '16 at 05:59