C/CPP-将浮点运算转换为整数运算
我有以下 c++ 函数(实现Bresenham's line algorithm),在书中看到
从像素到可编程图形硬件的计算机图形 作者 Alexey Boreskov, Evgeniy Shikin
其中一个函数使用浮点数,由于其效率低下,本书介绍了另一个仅使用整数算术的函数。
我很难理解为什么这两个是等价的,为什么我们<<在这里使用左移,而不是a<<1简单地乘以a2?
注:我们假设点A:(xa,ya)和B:(xb,yb)具有整数值。
浮动版
void drawLine(int xa, int ya, int xb, int yb, int color) {
float k = (float)(yb-ya)/(float)(xb-xa);
float d = 2*k - 1
int y = ya;
putPixel(xa, ya, color); // paint the pixel (xa,ya) in color "color"
for (int x = xa+1; x<=xb; x++) {
if (d > 0) {
d += 2*k + 2;
y++;
} else {
d += 2*k;
}
putPixel(x, y, color);
}
}
整数版本
void drawLine(int xa, int ya, int xb, int yb, int color) {
int dx = xb - xa;
int dy = yb -ya;
int d = (dy<<1) - dx;
int d1 = dy <<1;
int d2 = (dy - dx) << 1;
int y = ya;
putPixel(xa, ya, color); // paint the pixel (xa,ya) in color "color"
for (int x = xa+1; x<=xb; x++) {
if (d > 0) {
d += d2;
y++;
} else {
d += d1;
}
putPixel(x, y, color);
}
}
回答
浮点代码做了四件事d:
- 初始化
d为 2 dy / dx ?1,其中dy和dx是yb?ya和xb?xa, 分别。 - 评估是否
d大于 0。 - 将 2 dy / dx +2添加到
d. - 将 2 dy / dx添加到
d.
在浮点数中,除以dx可能会产生非整数。为了避免这种情况,我们通过将所有内容乘以dx 来转换操作,产生:
- 初始化
d为 2 dy?dx。 - 评估是否
d大于 0 dx(等于 0)。 - 将 2 dy +2 dx添加到
d。 - 将 2 dy添加到
d.
我们可以很容易地看到,除了 3 之外,这四个等效操作是在整数代码中实现的。整数代码似乎是将 2 dy ?2 dx添加到d。整数代码与Wikipedia 页面中显示的 Bresenham's line algorithm代码相匹配。我怀疑+浮点版本中的 是书中的错误。