1
\$\begingroup\$

I've written a method to obtain an IEnumerable from a start point, end point and step. Similar to Enumerable.Range() but for doubles and not fixed step.

public static IEnumerable<double> InclusiveRange(double start, double end, double step = 1)
    {
        while (start <= end)
        {
            yield return start;
            start += step;
        }
    }

Am I missing something, or there is a better approach?

\$\endgroup\$
3
\$\begingroup\$

As this is a quit nice approach, it is missing an important part.

Validation of input parameter

You should check at least the step parameter if it is a positive number greater 0.

InclusiveRange(1d, 5d,-1);  

the above call is by your definition a valid call, but can lead to a System.OutOfMemoryException if combined with the .ToList() extension method.

You need to decide if you want to enable negative step. If you don't want to allow negative values for step a simple guard clause can handle this.

if (step <= 0) { throw new ArgumentOutOfRangeException("step", "The value has to be greater than 0"); } 

But if you want to enable negative step values you need to add more checks and a different implementation.

A negative step means that start > end so you would need to introduce 2 more methods which you then call based on step beeing positive or negative.

private static IEnumerable<double> InclusiveRangeAscending(double start, double end, double step)  
{

}

private static IEnumerable<double> InclusiveRangeDescending(double start, double end, double step)  
{

}  

public static IEnumerable<double> InclusiveRange(double start, double end, double step = 1)
{
    if (step == 0) { throw new ArgumentOutOfRangeException("step", "The value has to be unequal to 0"); }
    if (step > 0)
    {
        return InclusiveRangeAscending(start, end, step);
    }
    else
    {
        return InclusiveRangeDescending(start, end, step);
    }
}
\$\endgroup\$
0
\$\begingroup\$

The use of integers with Enumerable.Range() produces fairly agreed-upon expected behaviors. But with doubles, you have introduced a mixed set of expectations.

Beside the validation of inputs as suggested by Heslacher, there is an issue of whether one would expect the end value to be included in the output. Given the nature of doubles and given start and step, there is no guarantee that you will land exactly on end. Maybe that's how you want it to be, but it is a new wrinkle that isn't in Enumerable.Range().

Also the name step is ambiguous to me. I'd prefer clarification as stepIncrement, which should be a positive or negative double, and numberOfSteps, which should be a positive int.

Sticking with double step or stepIncrement, there is a wrinkle over whether a 0 step is allowed. Heslacher's answer throws an exception. Another valid answer would be to simply return the start and end.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.