将while循环转为数学方程? [英] Turn while loop into math equation?

查看:135
本文介绍了将while循环转为数学方程?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have two simple while loops in my program that I feel ought to be math equations, but I'm struggling to convert them:

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)的中心的距离。

This code works as-is, but I feel it could be simplified into math equations. The idea here being that this code is taking an offset (someValue) and adjusting a coordinate (c) to minimize the distance from the center of a tile (of size someOtherValue). Any help would be appreciated.

推荐答案

可以证明以下是正确的:

It can be proved that the following is correct:

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

请注意,floor表示向下取整,向负无穷大:不向0.(例如floor(-3.1)= - 4。 floor()库函数会做到这一点;只是确保不会转换为int,通常会向0舍入。)

Note that floor means round down, towards negative infinity: not towards 0. (E.g. floor(-3.1)=-4. The floor() library functions will do this; just be sure not to just cast to int, which will usually round towards 0 instead.)

推测 b 是严格肯定的,因为否则两个循环都不会终止:添加 b 不会使 a 更大,减去 b 将不会使 a 有了这个假设,我们可以证明上面的代码工作。 (和paranoidgeek的代码也几乎是正确的,除了它使用转换为int而不是 floor 。)

Presumably b is strictly positive, because otherwise neither loop will never terminate: adding b will not make a larger and subtracting b will not make a smaller. With that assumption, we can prove that the above code works. (And paranoidgeek's code is also almost correct, except that it uses a cast to int instead of floor.)

聪明的证明方式
代码从 a b 的倍数$ c>直到 a 位于 [ - b / 2,b / 2)或从 a / b 中减去整数,直到 a / b 位于 [ - 1 / 2,1 / 2),即直到(a / b + 1/2) $ c> x )位于 [0,1)中。因为你只是通过整数来改变它, x 的值不会改变 mod 1 ,即它去 remaining mod 1 ,即 x-floor(x)。因此,您所做的有效减法数( c )为 floor(x)

Clever way of proving it: The code adds or subtracts multiples of b from a until a is in [-b/2,b/2), which you can view as adding or subtracting integers from a/b until a/b is in [-1/2,1/2), i.e. until (a/b+1/2) (call it x) is in [0,1). As you are only changing it by integers, the value of x does not change mod 1, i.e. it goes to its remainder mod 1, which is x-floor(x). So the effective number of subtractions you make (which is c) is floor(x).

乏味的验证方法


第一个循环, c 的值是循环运行次数的负数,即:

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 if:a> -b / 2 = a + b / 2> 0

  • -1 if:-b /2≥a> -3b / 2 =0≥a+ b / 2>-b≤0≥x> -1

  • -2 if:-3b /2≥a> -5b / 2 = -b-a + b / 2> -2b = -1 -1x≥-2等,

其中 x =(a + b / 2)/ b ,所以如果x> 0,c为0,否则为ceiling(x)-1。如果第一个循环完全运行,那么在执行循环之前,它是≤-b / 2,因此它是≤-b / 2 + b now,即≤b/ 2 。根据是否正好是b / 2(即,当你开始时是否 x 是否是一个非正整数),第二个循环完全运行1次或0,并且c是ceiling(x)或ceiling(x)-1。

where x = (a+b/2)/b, so c is: 0 if x>0 and "ceiling(x)-1" otherwise. If the first loop ran at all, then it was ≤ -b/2 just before the last time the loop was executed, so it is ≤ -b/2+b now, i.e. ≤ b/2. According as whether it is exactly b/2 or not (i.e., whether x when you started was exactly a non-positive integer or not), the second loop runs exactly 1 time or 0, and c is either ceiling(x) or ceiling(x)-1. So that solves it for the case when the first loop did run.

如果第一个循环没有运行,那么c在第二个循环结束时的值是:

If the first loop didn't run, then the value of c at the end of the second loop is:


  • 0如果:a< b / 2 = a-b / 2 < 0

  • 1如果:b /2≤a< 3b / 2 =0≤a-b / 2 < b <=0≤y< 1

  • 2 if:3b / 2≤a< 5b / 2 =b≤a-b / 2 < 2b =1≤y< 2等

其中 y =(ab / 2)/ b ,所以如果y <0,则c为:0,否则为1 + floor(y)。 [和 a 现在肯定< b / 2和≥-b / 2。]

where y = (a-b/2)/b, so c is: 0 if y<0 and 1+floor(y) otherwise. [And a now is certainly < b/2 and ≥ -b/2.]

因此,您可以为 c 写一个表达式: / p>

So you can write an expression for 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是整数)) floor(x)相同, floor(x + 1)-1 code> y 实际上是 x-1 ,因此(1 + floor(y))= floor x),并且对于条件:。
当x≤0时,不能是(y≥0),因此 c 只是第一项,它是 floor(x)

当0< x < 1,则这两个条件都不成立,因此 c 0 ;

x,那么只有0≤y,所以c只是第二项,它是 floor(x)
所有情况下c = floor(x)

Of course, next you notice that (ceiling(x)-1+(x is integer)) is same as floor(x+1)-1 which is floor(x), and that y is actually x-1, so (1+floor(y))=floor(x), and as for the conditionals:
when x≤0, it cannot be that (y≥0), so c is just the first term which is floor(x),
when 0 < x < 1, neither of the conditions holds, so c is 0,
when 1 ≤ x, then only 0≤y, so c is just the second term which is floor(x) again. So c = floor(x) in all cases.

这篇关于将while循环转为数学方程?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆