簡體   English   中英

浮點循環運行的迭代次數應該比應有的多

[英]Floating point loop runs more iterations than should be

我有這樣的循環這就是應該迭代lx超過X(范圍[-1,1])和倍ly超過y倍的(范圍[-1,1]),總9倍,但它迭代16倍! 為什么是這樣??

#include <stdio.h>

int main(void) {
  double lx=3,ly=3;
  double du = (1-(-1))/double(lx);
  double dv = (1-(-1))/double(ly);
  int count=0;

  for (double y=-1; y < 1; y += dv)
    for (double x=-1; x < 1; x += du) {

      count++;
    }

  printf("\n\n%d lss\n", count);
}

真的嗎?

你正在迭代[-1,-1 / 3,1 / 3,1]。

你可以通過在循環中放置一個輸出語句來查看發生了什么。

我假設你的C實現使用IEEE-754 64位二進制浮點數為double ,這是最常見的選擇。

每個數值運算系統都是不精確的,所以你使用的數字與精確數學所得的數字不同。

聲明double du = (1-(-1))/double(lx); du設置為最接近2/3的double值,即0.66666666666666662965923251249478198587894439697265625。

在外循環的第一次迭代中, y為-1。 在每次迭代結束時將du添加到其中時,結果為:

  • -0.33333333333333337034076748750521801412105560302734375,
  • 0.3333333333333332593184650249895639717578887939453125,和
  • 0.99999999999999988897769753748434595763683319091796875。

顯然, y最后一個值小於1,因此循環繼續進行另一次迭代。

循環迭代器通常應該使用整數值,因此很容易確保使用精確的算術。 您可以縮放迭代器以生成其他所需的值:

for (int iy = 0; iy < 4; ++iy)
{
    double y = iy * 2 / 3. - 1;
    …
}

你需要在這里以不同的方式計算起點和終點之間的差異,因為你在這里使用雙打。

因此,而不是end - start使用end - start + 1.0 ,你就完成了。

暫無
暫無

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

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