2

I have a loop inside a constructor, that creates and initialises a jagged array of objects. Inside the loop I have it print to the console on each iteration, so that I know how far through the process it is. It only prints to the console on a multiple of 5 (although it's only printing on a multiple of 10 for some reason) so that it doesn't spam the screen. Eg, 15% 20% 25%.

When I run the code on .Net 2.0 on Windows, it prints every 10% (rather than 5%). If I run the same code on Mono on an ARM machine it doesn't print any progress out at all.

  1. What is causing Mono to not give any output?
  2. Why is it printing only in increments of 10% rather than 5%?

Thanks

Here's the code:

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

2 回答 2

5

The problem is basically that you're performing an equality check on a floating point number, which is pretty much never a good idea.

This is better... but still not good:

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

That's still not going to print the percentage unless you end up exactly at multiples of 5%. So if there are 12 items, it's not going to work. Try this instead:

// 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;
}
于 2013-08-21T21:46:10.117 回答
1

floating point operations must be compared against the machine epsilon because of the floating point rounding errors

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

This expression can be never null according to the floating point rounding error

if (((double)x / Rows) * 100 % 5 == 0) must be if (Math.Abs(((double)x / Rows) * 100 % 5) < MACHINE_EPSILON)

But there is no definition in the .NET Framework for the machine epsilon. So don't use floating point operations for this at all or use a delta technique like

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

...
if((double)x / Rows) >= current)
{
    current += step;
    // Your code here
}
...
于 2013-08-21T22:19:21.500 回答