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:
Why is this returning an imprecise value?