我的程序中有两个简单的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
中添加或减去a
的倍数,直到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)
。证明oyt_rstrong的繁琐方式:
在第一个循环结束时,
c
的值是循环运行次数的负数,即:其中
x = (a+b/2)/b
,所以c为:如果x> 0则为0,否则为“ceiling(x)-1”。如果第一个循环完全运行,那么它恰好在上一次执行循环之前≤-b/2,所以现在≤-b/2 + b,即≤b/2。根据是否恰好是b/2(即,启动时的x
是否恰好是非正整数),第二个循环恰好运行1次或0,并且c是ceiling(x)或ceiling (x)-1。这样就解决了第一个循环确实运行的情况。如果第一个循环未运行,则第二个循环结束时c的值为:
其中
y = (a-b/2)/b
,所以c为:如果y a现在肯定是因此,您可以将
c
的表达式编写为: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
,因此是(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++ - 将while循环转换成数学方程式?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/392375/