Intervals or "ranges" are pretty common in programming, a lot of values are set in an interval of sorts and numeric types themselves are in their own range (int, double, long, short, unsigned, etc.). However, most languages don't support a simple way of declaring a custom interval.
value
[start, end] or die, or be forgiven
It's rather simple to disable assigning out-of-range values to a variable:
if (value >=
start && value <= end) my_range = value;
You can nicely pack the above statement into a property in C#:
double my_range;
double start, end;
double MyRange
{
get { return my_range; }
set { if (value >= start
&& value <= end) my_range = value; }
}
Now you can just write:
MyRange -= 3;
And it will update the variable only if the resulting value is in the [start, end] interval.
The above is perfectly fine if you want to keep it strict (can't drink 3 dL of water if there are only 2 dL left). But sometimes you might want be more forgiving (at least drink as much as it's possible):
if (value <
start)
my_range = start;
else if (value > end)
my_range = end;
else
my_range = value;
This will bring the value back to the closest limit when the value is out of range.
fall through a floor / jump through a ceiling
The previous code isn't convenient when you want to loop through an interval by incrementing or decrementing the value and letting it fall/jump through the limit. A typical example that I can think of is a slideshow of photos that automatically loops through the whole set. It gets to n-th photo, then starts again from the beginning.
The obvious way to implement this is simply checking the value if it's too low or high and setting it to the end or start, if it is. But this is nothing more than the "forgiving" code reversed:
if (value <
start)
my_range = end;
else if (value > end)
my_range = start;
else
my_range = value;
More precise way to loop through an interval is to add/subtract the rest of the value that was cut-off by the limit.
Suppose you have 1L bottle, 2/10 full, that can be refilled. Drinking 3 dL would result in the bottle being 9/10 full:
2/10 full >> drink 2 dL (0/10 full) >> refill (10/10 full) >> drink 1 dL (9/10 full)
For this to work we need the intervals to repeat themselves infinitely, meaning that where one ends, new one begins and vice-versa for negative infinity.
r: range size
s: range start
n: interval number
Range of integers:
[r * (n - 1) + s, r * n + s - 1] = { n
Z, r
N, s
Z }

Join the conversation! Your thoughts help the community grow.