环绕增量
我多年来一直在写长篇大论的东西是环绕增量。这实质上是添加到具有上限的值,并在达到该最大值时返回到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语句更快。