把while循环变成数学方程式?
我在我的程序中有两个简单的while循环,我觉得应该是数学方程,但我很难转换它们:
float a = someValue; int b = someOtherValue; int c = 0; while (a = b / 2) { c++; a -= b; }
这段代码按原样运行,但我觉得它可以简化为数学方程式。 这里的想法是这个代码采用偏移量(someValue)并调整坐标(c)以最小化距瓷砖中心的距离(大小为someOtherValue)。 任何帮助,将不胜感激。
可以certificate以下是正确的:
c = floor((a+b/2)/b) a = a - c*b
注意,floor表示向下舍入,朝向负无穷大:不向0(例如floor(-3.1)= – 4.lite floor()
库函数将执行此操作;只是确保不要仅转换为int,这通常是圆形反而朝向0。)
据推测b
是严格正的,因为否则两个循环都不会终止:添加b
不会变大,减去b
也不会变小。 有了这个假设,我们可以certificate上面的代码是有效的。 (并且paranoidgeek的代码也几乎是正确的,除了它使用转换为int而不是floor
。)
聪明的certificate方式 :代码在b
添加或减去b
倍数,直到a
在[-b/2,b/2)
,您可以将其视为从a/b
加上或减去整数 ,直到a/b
为止[-1/2,1/2)
,即直到(a/b+1/2)
(称之为x
)在[0,1)
。 因为你只用整数来改变它, x
的值不会改变mod 1
,即它会转到它的余数mod 1 ,即x-floor(x)
。 因此,您所做的减法的有效数量(即c
)是floor(x)
。
certificate它的繁琐方式 :
在第一个循环结束时, c
的值是循环运行次数的负数,即:
- 0如果:a> -b / 2 <=> a + b / 2> 0
- -1如果:-b /2≥a> -3b / 2 <=>0≥a+ b / 2> -b <=>0≥x> -1
- -2如果:-3b /2≥a> -5b / 2 <=>-b≥a+ b / 2> -2b <=>-1≥x> -2等,
其中x = (a+b/2)/b
,所以c为:0如果x> 0,则为“ceiling(x)-1”。 如果第一个循环完全运行,那么在最后一次执行循环之前它是≤-b / 2,所以它现在≤-b / 2 + b,即≤b/ 2。 根据它是否正好是b / 2(即,当你开始时x
是否恰好是一个非正整数),第二个循环恰好运行1次或0,c是天花板(x)或天花板(X)-1。 所以这解决了第一个循环运行时的情况。
如果第一个循环没有运行,那么第二个循环结束时c的值为:
- 0如果:a ab / 2 <0
- 1如果:b /2≤a<3b / 2 <=>0≤ab/ 2 0≤y<1
- 2如果:3b /2≤a<5b / 2 <=>b≤ab/ 2 <2b <=>1≤y<2等,
其中y = (ab/2)/b
,所以c为:如果y <0则为0,否则为1 + floor(y)。 [现在肯定是
所以你可以为c
写一个表达式:
x = (a+b/2)/b y = (ab/2)/b c = (x≤0)*(ceiling(x) - 1 + (x is integer)) +(y≥0)*(1 + floor(y))
当然,接下来你注意到(ceiling(x)-1+(x is integer))
与floor(x+1)-1
,即floor(x)
, y
实际上是x-1
,所以(1+floor(y))=floor(x)
,条件:
当x≤0时,它不能是(y≥0),所以c
只是第一项是floor(x)
,
当0 0
,
当1≤x时,则只有0≤y,所以c再次是第二项,即floor(x)
。 因此在所有情况下c = floor(x)
。
c = (int)((a - (b / 2)) / b + 1); a -= c * b;
测试案例访问http://pastebin.com/m1034e639
我想你想要这样的东西:
c = ((int) a + b / 2 * sign(a)) / b
这应该匹配你的循环,除了某些情况,其中b是奇数,因为当b是奇数时,-b / 2到b / 2的范围小于b。
假设b为正,则abs(c)= floor((abs(a)-b / 2)/ b)。 然后,将a的符号应用于c。