【问题标题】:C/CPP - Converting floating point arithmetic to integer arithmeticC/CPP - 将浮点运算转换为整数运算
【发布时间】:2021-08-11 09:42:00
【问题描述】:

我有以下c++函数(实现Bresenham's line algorithm),在书中看到

从像素到可编程图形硬件的计算机图形 Alexey Boreskov,Evgeniy Shikin

其中一个函数使用浮点数,由于效率低下,本书介绍了另一个仅使用整数运算的函数。

我很难理解为什么这两个是等价的,为什么我们在这里使用左移 <<a<<1 不是简单地将 a 乘以 2?

注意:我们假设点 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);
    }
}

【问题讨论】:

  • 旧编译器使用value &lt;&lt; 1 可能比使用value * 2 发出更好(对于更好 的合适值)代码。当前的编译器将发出相同的代码。
  • @pmg 我仍然不清楚为什么这些函数是等价的,如果我们从不使用除法,它们怎么能给出相同的输出(例如,我认为斜率 k 必须用除法表示,但在第二个函数中没有k,也没有除法)
  • 啊...你的问题比我想象的要深,抱歉。
  • 所有 ds 在 int 版本中都大 dx 倍。因为它们只与零进行比较……我确实看到了一个拼写错误,一个 + 和 - 交换了?
  • @Yakk-AdamNevraumont 我没有错别字,我不能说本书作者是否有错别字

标签: c++ c algorithm floating-point integer


【解决方案1】:

浮点代码用d做四件事:

  1. d初始化为2dy/dx-1,其中dydx是@987654324 @−yaxbxa
  2. 判断d是否大于0。
  3. 将 2dy/dx+2 添加到 d
  4. 将 2dy/dx 添加到 d

在浮点中,除以 dx 可能会产生非整数。为了避免这种情况,我们通过将所有内容乘以 dx 来转换操作,得到:

  1. d初始化为2dy-dx
  2. 评估d 是否大于0dx(等于0)。
  3. 将 2dy+2dx 添加到 d
  4. 将 2dy 添加到 d

我们可以很容易地看到这四个等效操作是在除 3 之外的整数代码中实现的。整数代码似乎将 2dy-2dx 添加到 @987654335 @。整数代码与the Wikipedia page for Bresenham’s line algorithm 中显示的代码匹配。我怀疑浮点版本中的+ 是书中的错误。

【讨论】:

  • 书上好像有错别字,谢谢解释
猜你喜欢
  • 2013-06-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-19
  • 1970-01-01
  • 1970-01-01
  • 2016-08-23
相关资源
最近更新 更多