Twin Primes Segmented Sieve of Zakiya (SSoZ) Explained

kdevel kdevel at vogtner.de
Sat Jun 18 21:01:04 UTC 2022


On Saturday, 18 June 2022 at 20:21:17 UTC, Salih Dincer wrote:

- Have you tried to compile your code with dmd/gdc before pasting?
- I can't read the 2.iota-stuff. Are you trying to avoid writing 
a raw for-loop?

```
$ pr.d(10): Error: none of the overloads of template 
`pr.main.each!((end_num)
{
const double test = end_num * end_num;
const testType root1 = cast(testType)realSqrt(test);
const testType root2 = sqrt!testType(end_num * end_num);
if (root2 != end_num)
{
writefln("%s: %s == %s", end_num, root1, root2);
}
assert(root2 == end_num);
count++;
}
).each` are callable using argument types `!()(Result)`
[...]/linux/bin64/../../src/phobos/std/algorithm/iteration.d(908):        Candidates are: `each(Range)(Range r)`
   with `Range = Result`
   must satisfy one of the following constraints:
`       isRangeIterable!Range
        __traits(compiles, typeof(r.front).length)`
[...]/linux/bin64/../../src/phobos/std/algorithm/iteration.d(969):                        `each(Iterable)(auto ref Iterable r)`
   with `Iterable = Result`
   must satisfy one of the following constraints:
`       isForeachIterable!Iterable
        __traits(compiles, Parameters!(Parameters!(r.opApply)))`
```

> In fact, realSqrt() will give incorrect results when it 
> approaches 100 million. Because there are losses in type 
> conversions.

Do you mean this:

```
const double test = end_num * end_num;
```

The loss of precision is due to the integer overflow before the 
assignment to test. It has nothing to do with the double 
precision variable test which has a mantissa of 53 bits.

```hm.d
import std.stdio;
import std.conv;
import std.math;
import std.exception;

void radix (uint i)
{
    double d = i;
    d *= i;
    // writefln!"d = %f" (d);
    double root = sqrt (d);
    // writefln!"root = %f" (root);
    uint rdx = cast (uint) root;
    enforce (rdx == i);
}

void main (string [] args)
{
    enforce (args.length == 3);
    uint first = args [1].to!uint;
    enforce (first >= 0);
    uint last = args [2].to!uint;
    enforce (last >= 1);
    enforce (last < last.max);
    enforce (last > first);
    for (uint i = first; i <= last; ++i)
       radix (i);
    writeln ("success");
}
```

No problem when approaching 100_000_000:

```
$ ./hm 9000 10000
success
```


More information about the Digitalmars-d mailing list