2013-08-21 94 views
2

我在構造函數中有一個循環,它創建並初始化一個鋸齒狀的對象數組。在循環內部,我會在每次迭代時將它打印到控制檯,這樣我就知道它的過程有多遠。它僅以5的倍數打印到控制檯(儘管由於某種原因它只打印在10的倍數上),因此它不會使屏幕垃圾郵件。例如,15%20%25%。C#檢查進度的奇怪問題

當我在Windows上運行.Net 2.0上的代碼時,它每打印10%(而不是5%)。如果我在ARM機器上的Mono上運行相同的代碼,它根本不打印任何進度。

  1. 什麼是造成莫諾不給任何輸出?
  2. 爲什麼它僅以10%而不是5%的增量進行打印?

感謝

下面的代碼:

public Map(int NumberOfRows, int NumberOfColumns) 
{ 
    Rows = NumberOfRows; 
    Columns = NumberOfColumns; 

    TileGrid = new Tile[NumberOfRows][]; 
    for (int x = 0; x < TileGrid.Length; x++) 
    { 
     TileGrid[x] = new Tile[NumberOfColumns]; 
     for (int y = 0; y < TileGrid[x].Length; y++) 
     { 
      TileGrid[x][y] = new Tile(); 
     } 

     if (((double)x/Rows) * 100 % 5 == 0) 
     { 
      Console.WriteLine("{0}%", ((double)x/Rows) * 100); 
     } 
    } 
} 
+2

您使用'double'這一事實是問題所在。雙**有**不夠精確**。 –

回答

5

的問題基本上是你執行一個浮點數,這是相當多的不是一個好主意相等性檢查。

這是更好 ...但還是不擅長:

int percentage = (x * 100)/Rows; 
if (percentage % 5 == 0) 
{ 
    Console.WriteLine("{0}%", percentage); 
} 

這仍然不會,除非你最終正好在5%的倍數打印的百分比。所以如果有12個項目,它不會起作用。試試這個:

// Before the loop 
int lastPrintedPercentage = -5; // So that we always print on the first loop 

// Within the loop 
int percentage = (x * 100)/Rows; 
if (percentage >= lastPrintedPercentage + 5) 
{ 
    Console.WriteLine("{0}%", percentage); 
    lastPrintedPercentage = percentage; 
} 
+0

這很好,謝謝!在x86和ARM/Mono上。 – user9993

1

浮點運算必須與機器精度進行比較,因爲浮點的舍入誤差

http://en.wikipedia.org/wiki/Machine_epsilon

該表達式可以根據浮點舍入誤差不能爲null

如果(((雙)X /行)×100%5 == 0) 必須是 如果(Math.Abs​​(((雙)X /行)×100%5)< MACHINE_EPSILON)

但是在.NET Framework中沒有定義機器epsilon。因此,根本不要使用浮點運算或使用delta技術,如

var step = (double)x/Rows) * 5; 
var current = step ; 

... 
if((double)x/Rows) >= current) 
{ 
    current += step; 
    // Your code here 
} 
...