我们如何在没有条件的情况下递增然后递减计数器?
Posted
技术标签:
【中文标题】我们如何在没有条件的情况下递增然后递减计数器?【英文标题】:How can we increment and then decrement a counter without conditionals? 【发布时间】:2014-12-22 19:44:48 【问题描述】:我正在寻找一种巧妙的方法来增加然后减少计数器变量。我希望计数器变量以较低的值开始并递增,向更高的值。一旦达到较高的值,计数器就会递减,直到回到较低的值。一旦达到较低的值,计数器就会再次增加到较高的值......我想你明白了。
我正在处理canvas animation,我想在其中使用一些聪明才智,而不使用if
或其他条件测试:
这里是处理计数器变量的条件逻辑:
incrementing = true
foo = ->
length += 1 if incrementing
length -= 1 if not incrementing
incrementing = false if length > 100
incrementing = true if length < 1
最初,我认为我可以使用模数。但是,模除法只会将计数器重置回较低的值——一旦达到最大值,它不会递减计数器。
0 % 10 = 0
1 % 10 = 1
2 % 10 = 2
3 % 10 = 3
4 % 10 = 4
5 % 10 = 5
6 % 10 = 6
7 % 10 = 7
8 % 10 = 8
9 % 10 = 9
10 % 10 = 0
11 % 10 = 1
12 % 10 = 2
13 % 10 = 3
我确信必须有一种方法可以在不使用条件测试的情况下做到这一点。假设底部值为 0,顶部值为 10,则该方法应输出以下内容。
? = 0
? = 1
? = 2
? = 3
? = 4
? = 5
? = 6
? = 7
? = 8
? = 9
? = 8
? = 7
? = 6
? = 5
【问题讨论】:
+1
需要一个完全非问题的解决方案,纯粹是为了让你的代码更漂亮。这就是我们学习 CoffeeScript 的原因。
【参考方案1】:
首先让我们看一些波浪!
你好挥手!
您能找出符合您需求的那一款吗?
如果你猜对了Triangle Wave,那你就猜对了!
三角波以均匀斜率振荡,直到达到最小值或最大值,然后斜率反转。
这里需要解决两件事:
函数的起点将从波浪的中间开始 波从x
振荡到-x
我们希望从0
开始输出,并且只包含正值
function triangle(t, a)
return Math.abs(((t + a/2) % a) - a/2);
我们来试试吧
for (var i=0; i<20; i++)
console.log(i, triangle(i, 10));
输出
0 0
1 1
2 2
3 3
4 4
5 5
6 4
7 3
8 2
9 1
10 0
11 1
12 2
13 3
14 4
15 5
16 4
17 3
18 2
19 1
所以当我们调用triangle(i, 10)
时,10
就是“句号”。这告诉我们在函数重复之前我们希望在函数中执行多少步。
6
的句点会给我们 6 个值,0, 1, 2, 3, 2, 1
4
的句点会给我们 4 个值,0, 1, 2, 1
等
如果你想从0-9
出发,你需要一段20
【讨论】:
这里是锯齿版本。用于重置回 0function sawtooth(t, a) return Math.abs(((t + a) % a));
【参考方案2】:
这是一个:
(x&8)+(x&7)*((~x&8)/4-1)
这会给你
0,1,2,3,4,5,6,7,8,7,6,5,4,3,2,1,0,1,...
当然里面实际上有一个条件,只是隐藏为按位运算。
另一种可能性是三角波计数器:
(x^((x&8)/-8))&7
会的
0,1,2,3,4,5,6,7,7,6,5,4,3,2,1,0,0,...
还有一个隐藏的条件,它会在中途翻转位。
【讨论】:
以上是关于我们如何在没有条件的情况下递增然后递减计数器?的主要内容,如果未能解决你的问题,请参考以下文章
shared_ptrs 是不是由于引用计数器原子递增/递减而遇到缓存未命中?