【发布时间】:2015-08-17 02:00:29
【问题描述】:
我试图在game_width=640 和game_height=480 的窗口内绘制一个网格。网格单元的数量是预定义的。我想水平和垂直均匀分布单元格。
void GamePaint(HDC dc)
{
int numcells = 11;
for(int i = 1; i <= numcells; i++)
{
int y = <INSERT EQUATION>;
MoveToEx(dc, 0, y, NULL);
LineTo(dc, game_width, y);
}
// solving the horizontal equation will in turn solve the vertical one so no need to show the vertical code
}
想到的第一个等式是:
i * (game_height / numcells)
这背后的概念是将总高度除以单元格的数量以获得偶数单元格大小,然后在循环的每次迭代中将其乘以i以获得正确的y坐标水平线。
问题在于它似乎在最后留下了一个额外的小单元:
我认为这一定与积分除法有关,所以我们得出第二个等式:
(int)(i * ((float)game_height / numcells))
这个想法是避免整数除法,进行浮点除法,像以前一样乘以 i 并将结果转换回 int。这很好用,最后没有额外的小单元格!
让我抓狂的是这个等式:
i * game_height / numcells
这似乎与前面的等式具有相同的效果,但当然还有不进行任何强制转换的额外好处。我不明白为什么这不会受到第一个等式中整数除法问题的影响。
注意数学上:X * (Y / Z) == X * Y / Z 所以第一个方程的整数除法肯定有问题。
Here's a video 在调试器观察窗口中观察这 3 个方程。
随着i 的增加,您可以看到第一个等式的结果与第二个和第三个等式(始终具有相同的结果)之间的差距越来越大。
为什么第三个方程和第二个方程一样给出正确的结果,而没有受到第一个方程的积分除法误差的影响?我似乎无法理解它......
感谢任何帮助。
【问题讨论】:
标签: c++ winapi math integer-division