Why is this code slow?

Salih Dincer salihdb at hotmail.com
Tue Mar 26 13:57:22 UTC 2024


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 at 79


More information about the Digitalmars-d-learn mailing list