I need to write an integer that "circulates" between a minimum and maximum value. If the maximum value is reached and you add 1, it jumps to the minimum value. If you subtract 1 from the minimum value you reach the maxValue.
Example:
minValue = 2;
maxValue = 10;
leads to: ... 2,3,4,...9,10,2,3,...
I figured out the addition algorithm, but I'm stuck with the subtraction. Addition looks like this:
public static circularInt operator +(circularInt a, int b)
{
int sum = a.value + b;
int circularValue = ((sum - a.minValue) % (a.maxValue + 1 - a.minValue)) + a.minValue;
return new circularInt(circularValue, a.minValue, a.maxValue);
}
Basically the algorithm can be broken down to "newValue % range". All the +- minValue is just to eliminate it from the calculation, and add it later on again.
Is there a known algorithm for this? If not, do you have an idea how the subtraction algorithm might look like?
Start by applying the modulo to b
and subtracting the minimum from a.value
int range = a.maxValue + 1 - a.minValue;
b %= range;
int value = a.value - a.minValue;
Allowing for negative values, b
will now be greater than -range
and less than range
.
For addition, add b
and the range
to the value
, and apply the modulo. Adding the range
is necessary when b
is a negative number. Adding a negative number is the same as subtracting a positive number.
int result = (value+range+b) % range;
For subtraction, add the range
to the value
before subtracting b
, and apply the modulo. This works because (value+range) % range == value
so adding the range doesn't change the final result, but it does keep the intermediate result from going negative.
int result = (value+range-b) % range;
Finish by adding the minimum back in
int circularValue = result + a.minValue;
Here's the final code, courtesy of @Meister der Magie
Addition:
public static circularInt operator +(circularInt a, int b)
{
int range = (a.maxValue + 1 - a.minValue);
b %= range;
int value = a.value - a.minValue;
int additionResult = (value+range+b) % range;
int circularValue = additionResult + a.minValue;
return new circularInt(circularValue, a.minValue, a.maxValue);
}
Subtraction:
public static circularInt operator -(circularInt a, int b)
{
int range = (a.maxValue + 1 - a.minValue);
b %= range;
int value = a.value - a.minValue;
int subtractionResult = (value+range-b) % range;
int circularValue = subtractionResult + a.minValue;
return new circularInt(circularValue, a.minValue, a.maxValue);
}