将while循环转为数学方程? [英] Turn while loop into math equation?
问题描述
我在程序中有两个简单的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屋!