环绕增量
我多年来一直在写长篇大论的东西是环绕增量。这实质上是添加到具有上限的值,并在达到该最大值时返回到0。
这可以通过if语句来完成,在本例中我使用的是PHP,但其他语言中的想法是相同的。
/**
* 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;
}这个函数可以很简单地使用,例如,如果我们尝试增加一个处于最大边界值的数字,那么该函数将返回0。
echoboundedIncrement(500,500);//prints0
使用纯数学更简单的方法是使用我最近发现的简洁的模数技巧。
通过将增量值添加到最大值,然后对最大值执行模数计算,我们基本上会自动再次返回到0。请注意,为了正确环绕开始,我们需要将最大值加1。
这是新函数,它的工作方式与前一个函数相同,因为我们不能增加超过最大数字的值。
/**
* 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);
}与此类似,我们也可以用同样的方式递减。在这种情况下,当我们达到0时,数字将再次循环回到最大数字。
/**
* 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);
}以下是对这些功能的一些实际测试。
echo boundedIncrement(0, 500); //prints1 echo boundedIncrement(1, 500); //prints2 echo boundedIncrement(250, 500); //prints251 echo boundedIncrement(499, 500); //prints500 echo boundedIncrement(500, 500); //prints0 echo boundedDecrement(0, 500); //prints500 echo boundedDecrement(1, 500); //prints0 echo boundedDecrement(250, 500); //prints249 echo boundedDecrement(499, 500); //prints498 echo boundedDecrement(500, 500); //prints499
这种方法的一个怪癖是我们实际上可以发送超出有界范围的数字,但仍然可以接收一个有意义的数字。这不是我们开始使用的简单if语句函数所涵盖的。
echo boundedIncrement(501, 500); //prints1 echo boundedIncrement(600, 500); //prints100 echo boundedDecrement(501, 500); //prints500 echo boundedDecrement(600, 500); //prints98
我们可以通过添加一个允许我们更改增量量的参数来增强这些功能。
/**
* 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);
}在查看生成图形或元胞自动机时,这些函数(以及它们背后的数学)很有用。它允许我们从上到下或从左到右循环,而无需在代码中使用大量if语句。此外,因为这只是使用数学方法来执行环绕它实际上比运行if语句更快。