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