number ranges
Salih Dincer
salihdb at hotmail.com
Fri Jan 21 16:58:37 UTC 2022
On Thursday, 20 January 2022 at 16:33:20 UTC, Ali Çehreli wrote:
>
> So if we add the 1.0 value after 0.9000000357627869 to be
> *inclusive*, then that last step would not be 0.3 anymore.
> (Thinking about it, step would mess up things for integral
> types as well; so, it must be checked during construction.)
>
> The other obvious issue in the output is that a floating point
> iota cannot be bidirectional because the element values would
> be different.
The test that did not pass now passes. There is the issue of
T.min being excluded from the property list for the double type.
I tried to solve it, how is it?
Salih
```d
auto inclusiveRange(T)(T f, T l, T s = cast(T)0)
in(!isBoolean!T) {
static assert(!isBoolean!T, "\n
Cannot be used with bool type\n");
if(!s) s++;
return InclusiveRange!T(f, l, s);
}
struct InclusiveRange(T) {
private:
T first, last;
bool empty_;
public:
T step;
this(U)(in U first, in U last, in U step)
in (first <= last, format!"\n
Invalid range:[%s,%s]."(first, last))
{
this.first = first;
this.last = last;
this.step = step;
this.empty_ = false;
}
bool opBinaryRight(string op:"in")(T rhs) {
foreach(r; this) {
if(r == rhs) return true;
}
return false;
}
auto save() inout { return this; }
bool empty() inout { return empty_; }
T front() inout { return first; }
T back() inout { return last; }
void popFront() {
if(!empty) {
if(last >= first + step) {
first += step;
} else {
empty_ = true;
if(T.max <= first + step) {
first += step;
}
}
}
}
void popBack() {
if(!empty) {
if(first <= last-step) {
last -= step;
} else {
empty_ = true;
if(!T.max >= last - step) {
last -= step;
}
}
}
}
size_t length() inout {
auto len = 1 + (last - first) / step;
return cast(size_t)len;
}
}
import std.algorithm, std.math;
import std.range, std.traits;
import std.stdio, std.format, std.conv;
void main() {
// Pi Number Test
auto GregorySeries = inclusiveRange!double(1, 0x1.0p+27, 2);
double piNumber = 0;
foreach(e, n; GregorySeries.enumerate) {
if(e & 1) piNumber -= 1/n;
else piNumber += 1/n;
}
writefln!"%.21f (constant)"(PI);
writefln!"%.21f (calculated)"(piNumber * 4);
} unittest {
// Should not be possible to have an empty range
auto r = inclusiveRange(ubyte.min, ubyte.max);
static assert(is(ElementType!(typeof(r)) == ubyte));
assert(r.sum == (ubyte.max * (ubyte.max + 1)) / 2);
}
```
More information about the Digitalmars-d-learn
mailing list