Something I've been writing long hand for a number of years is wrap around increments. This is essentially adding to a value that has an upper limit, and wrapping back to 0 when that max value is reached.
This can be done with an if statement, in this case I'm using PHP, but the idea is the same in other languages.
/**
* Increment within a upper bound.
*
* @param int $number
* The number to increment.
* @param int $max
* The upper bound of the number.
*
* @return int
* The bounded incremented number.
*/
function boundedIncrement($number, $max) {
$number++;
if ($number > $max) {
$number = 0;
}
return $number;
}
This function can be used simply enough, for example, if we try to increment a number that is at the maximum bound value then the function will return 0.
echo boundedIncrement(500, 500); // prints 0
A simpler approach to this using pure maths is to use a neat modulus trick, which I found recently.
By adding the incremented value to the maximum value and then performing a modulus calculation on the maximum we essentially automatically wrap around to 0 again. Note that in order to wrap around to the start correctly we need to add 1 to the max value.
Here is the new function, which works in the same way as the previous one in that we can't increment above the value of the max number.
/**
* Increment within a upper bound.
*
* @param int $number
* The number to increment.
* @param int $max
* The upper bound of the number.
*
* @return int
* The bounded incremented number.
*/
function boundedIncrement($number, $max) {
return (($number + 1) + ($max + 1)) % ($max + 1);
}
Similar to this, we can also decrement in the same way. In this case when we reach 0 the number will loop back to the max number again.
/**
* Decrement within an upper bound.
*
* @param int $number
* The number to decrement.
* @param int $max
* The upper bound of the number.
*
* @return int
* The bounded decremented number.
*/
function boundedDecrement($number, $max) {
return (($number - 1) + ($max + 1)) % ($max + 1);
}
Here are some tests of these functions in action.
echo boundedIncrement(0, 500); // prints 1
echo boundedIncrement(1, 500); // prints 2
echo boundedIncrement(250, 500); // prints 251
echo boundedIncrement(499, 500); // prints 500
echo boundedIncrement(500, 500); // prints 0
echo boundedDecrement(0, 500); // prints 500
echo boundedDecrement(1, 500); // prints 0
echo boundedDecrement(250, 500); // prints 249
echo boundedDecrement(499, 500); // prints 498
echo boundedDecrement(500, 500); // prints 499
One quirk of this method is that we can actually send numbers that are outside of the bounded range and still receive a number that makes sense. This isn't covered by the simple if statement function that we started with.
echo boundedIncrement(501, 500); // prints 1
echo boundedIncrement(600, 500); // prints 100
echo boundedDecrement(501, 500); // prints 500
echo boundedDecrement(600, 500); // prints 98
We can enhance these functions by adding a parameter that allows us to change the amount of increment.
/**
* Increment within a upper bound.
*
* @param int $number
* The number to increment.
* @param int $max
* The upper bound of the number.
* @param int $delta
* The number to increment by.
*
* @return int
* The bounded incremented number.
*/
function boundedIncrement($number, $max, $delta = 1) {
return (($number + $delta) + ($max + 1)) % ($max + 1);
}
/**
* Decrement within an upper bound.
*
* @param int $number
* The number to decrement.
* @param int $max
* The upper bound of the number.
* @param int $delta
* The number to decrement by.
*
* @return int
* The bounded decremented number.
*/
function boundedDecrement($number, $max, $delta = 1) {
return (($number - $delta) + ($max + 1)) % ($max + 1);
}
These functions (and the maths behind them) are useful when looking at producing graphics or cellular automata. It allows us to loop around from top to bottom or from left to right without having lots of if statements in the code. Also, because this is just using a mathematical method to perform the wrap around it is actually quicker than running if statements.
Add new comment