把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 c为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。