On Monday, 25 March 2024 at 14:02:08 UTC, rkompass wrote:
Of course you may also combine the up(+) and down(-) step to
one:
1/i - 1/(i+2) = 2/(i*(i+2))
```d
double leibniz(int iter) {
double n = 0.0;
for (int i = 1; i < iter; i+=4)
n += 2.0 / (i * (i+2.0));
return n * 4.0;
}
```
or even combine both approaches. But of, course mathematically
much more is possible. This was not about approximating pi as
fast as possible...
The above first approach still works with the original speed,
only makes the result a little bit nicer.
It's obvious that you are a good mathematician. You used sequence
A005563. First of all, I must apologize to the questioner for
digressing from the topic. But I saw that there is a calculation
difference between real and double. My goal was to see if there
would be a change in speed. For example, with 250 million cycles
(iter/4) I got the following result:
3.14159265158976691 (250 5million (with real)
3.14159264457621568 (250 million with double)
3.14159265358979324 (std.math.constants.PI)
First of all, my question is: Why do we see this calculation
error with double? Could the changes I made to the algorithm
have caused this? Here's an executable code snippet:
```d
enum step = 4;
enum loop = 250_000_000;
auto leibniz(T)(int iter)
{
T n = 2/3.0;
for(int i = 5; i < iter; i += step)
{
T a = (2.0 + i) * i; // https://oeis.org/A005563
n += 2/a;
}
return n * step;
}
import std.stdio : writefln;
void main()
{
enum iter = loop * step-10;
65358979323.writefln!"Compare.%s";
iter.leibniz!double.writefln!"%.17f (double)";
iter.leibniz!real.writefln!"%.17f (real)";
imported!"std.math".PI.writefln!"%.17f (enum)";
} /* Prints:
Compare.65358979323
3.14159264457621568 (double)
3.14159265158976689 (real)
3.14159265358979324 (enum)
*/
```
In fact, there are algorithms that calculate accurately up to 12
decimal places with fewer cycles. (e.g. 9999)
SDB@79