Possible compiler bug?

  • Thread starter Thread starter anon
  • Start date Start date
A

anon

I am not quick to leap to this conclusion, but...

I have a bit of code for doing a color space conversion (RGB to HSB). This
is not a trvial conversion but it isn't that complicated either. It is just
really a 3D coordinate conversion.

It works perfectly well in the IDE. When running the application direcly, it
mainly works, except for a certain narrow band of colors the calculation
goes wrong.

Unfortunately, any attempt to add debug seems to make the problem disappear.
Indeed, even the inclusion of a line of code which has no effect, eg int x =
y; when x is never used again, makes the problem go away.

The only remotely dodgy thing about the code (it is "standard" code, at
least in its C++ form, I didn't write it) is that it compares 2 floats for
equality. To be fair, it first assigns a to b, and then later tests if a==b,
so it should work.

Howevr I wonder if some compiler bug is mistakenly deciding the values
cannot be equal in some cases.

Anyway I changed the logic to use flags and it works. But that diesn't prove
much.

Dom

Stunning fractal photographs
http://www.morello.co.uk/fractal.htm
 
Would be nice if you could post some code.
But the float comparison could be the reason since calculated float values
are sometimes stored into 80 bit registers and sometimes into 64 bit
registers.
And if you assign a flaot that is stored in a 80 bit register to one that is
stored in a 64 bit register you can lose some digits and successive equality
tests will give false even the same value was originally assigned to both of
them.
 
If I could find a small bit of code which showed the problem I would post
it - but even tiny changes to the code seem to alter the situation so I am
doubtful of the chances of finding a small example. The problem is in the
middle of a large library.

What you are saying seems to make sense (at least, yet another straw to
clutch at :) Do you know how the compiler would choose which type of float
to use? Why would it be different for the IDE?

Would it help to use doubles? Your theory would explain why my alternative
flag implementation works, at least.

Dom
 
[Removed invalid group microsoft.public.dotnet.csharp.general]

anon said:
I am not quick to leap to this conclusion, but...

I have a bit of code for doing a color space conversion (RGB to HSB). This
is not a trvial conversion but it isn't that complicated either. It is just
really a 3D coordinate conversion.

It works perfectly well in the IDE. When running the application direcly, it
mainly works, except for a certain narrow band of colors the calculation
goes wrong.

Unfortunately, any attempt to add debug seems to make the problem disappear.
Indeed, even the inclusion of a line of code which has no effect, eg int x =
y; when x is never used again, makes the problem go away.

The only remotely dodgy thing about the code (it is "standard" code, at
least in its C++ form, I didn't write it) is that it compares 2 floats for
equality. To be fair, it first assigns a to b, and then later tests if a==b,
so it should work.

No - that isn't guaranteed to work. The no-op code you wrote is
probably having an effect on the JIT to force it to use just 64-bit or
32-bit values rather than the 80-bit register values, as cody said.
Here's a sample program which demonstrates the same kind of effect:

using System;

class Test

{

static float member;

static void Main()
{
member = Calc();
float local = Calc();
Console.WriteLine(local==member);
// Console.WriteLine (local);
}

static float Calc()
{
float d1 = 2.82323f;
float d2 = 2.3f;
return d1*d2;
}

}

As written, it prints "False" on my box. Removing the comment makes it
print "True" as the first line.

Using doubles *may* help, but it's not really a guaranteed way of doing
things. I'd suggest defining some range of values as being "effectively
equal" - take the difference between the two values, and see whether or
not it's smaller than either a fixed number, or some proportion of the
original numbers. (So 99 and 100 may not be "close enough" but 9999999
and 10000000 may be.)
 
Back
Top