将 while 循环转化为数学方程?

2023-12-20

我的程序中有两个简单的 while 循环,我认为它们应该是数学方程,但我正在努力转换它们:

float a = someValue;
int b = someOtherValue;
int c = 0;

while (a <= -b / 2) {
    c--;
    a += b;
}
while (a >= b / 2) {
    c++;
    a -= b;
}

这段代码按原样工作,但我觉得它可以简化为数学方程。这里的想法是,此代码采用偏移量 (someValue) 并调整坐标 (c),以最小化与图块(大小为 someOtherValue)中心的距离。任何帮助,将不胜感激。


可以证明以下说法是正确的:

c = floor((a+b/2)/b)
a = a - c*b

请注意,floor 表示向下舍入,朝向负无穷大:而不是朝向 0。(例如,floor(-3.1)=-4。floor()库函数将执行此操作;请确保不要只转换为 int,它通常会向 0 舍入。)

想必b严格为正,因为否则两个循环都不会终止:添加b不会使a更大和减去b不会使a较小。有了这个假设,我们就可以证明上面的代码是有效的。 (paranoidgeek 的代码也几乎是正确的,除了它使用强制转换为 int 而不是floor.)

巧妙的证明方法: 该代码添加或减去的倍数b from a until a is in [-b/2,b/2),您可以将其视为加法或减法integers from a/b until a/b is in [-1/2,1/2),即直到(a/b+1/2)(叫它x) is in [0,1)。由于您仅按整数更改它,因此值x没有改变mod 1,即它转到它的余数模 1,即x-floor(x)。因此,您进行的有效减法次数(即c) is floor(x).

乏味的证明方式:

At the end of the first loop, the value of c is the negative of the number of times the loop runs, i.e.:

  • 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 等等,

where 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 a-b/2
  • 1 如果:b/2 ≤ a 0 ≤ a-b/2 0 ≤ y
  • 2 如果:3b/2 ≤ a b ≤ a-b/2 1 ≤ y

where y = (a-b/2)/b,所以 c 为:如果 ya现在肯定是

所以你可以写一个表达式c as:

x = (a+b/2)/b
y = (a-b/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, so (1+floor(y))=floor(x),至于条件:
当x≤0时,不可能有(y≥0),所以c只是第一项floor(x),
当 0 c is 0,
当 1 ≤ x 时,只有 0≤y,所以 c 只是第二项,即floor(x)再次。 所以c =floor(x)在所有情况下。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

将 while 循环转化为数学方程? 的相关文章

随机推荐