簡體   English   中英

C/CPP - 將浮點運算轉換為 integer 運算

[英]C/CPP - Converting floating point arithmetic to integer arithmetic

我有以下 c++ 函數(實現Bresenham 的線算法),在書中看到

從像素到可編程圖形硬件的計算機圖形 作者 Alexey Boreskov, Evgeniy Shikin

其中一個 function 使用浮點數,由於效率低下,本書提出了另一個 function 僅使用 integer 算術。

我很難理解為什么這兩個是等價的,為什么我們在這里使用左移<<a<<1不是簡單地將a乘以 2 嗎?

注意:我們假設點A:(xa,ya)B:(xb,yb)具有 integer 值。


浮動版本

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);
    }
}

Integer版

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做了四件事:

  1. d初始化為 2 dy / dx -1,其中dydx分別是yb - yaxb - xa
  2. 評估d是否大於 0。
  3. 將 2 dy / dx +2 添加到d
  4. 將 2 dy / dx添加到d

在浮點數中,除以dx可能會產生非整數。 為了避免這種情況,我們通過將所有內容乘以dx來轉換操作,得到:

  1. d初始化為 2 dy - dx
  2. 評估d是否大於 0 dx (等於 0)。
  3. 將 2 dy +2 dx添加到d
  4. 將 2 dy添加到d

我們可以很容易地看到這四個等效操作在 integer 代碼中實現,除了 3。integer 代碼似乎將 2 dy -2 dx添加到d integer 代碼與Wikipedia 頁面中顯示的 Bresenham 線算法代碼相匹配。 我懷疑浮點版本中的+是書中的錯誤。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM