In my program, this snippet:
trace.log( String.Format("a= {0:R} b= {1:R} a<b= {2}", b.GetPixel(447, 517).GetBrightness(), (100F / 255F), b.GetPixel(447, 517).GetBrightness() < (100F / 255F)) );
displays this in Debug \ prog.exe:
a= 0.392156869 b= 0.392156869 a<b= False
but this other result in Release \ prog.exe:
a= 0.392156869 b= 0.392156869 a<b= True
Can someone explain why the same operands give a different comparison result? And recommend a security tool, ideally the same software as the compiler? Thanks.
EDIT: Explanation: The above results run Debug \ prog.exe and Release \ prog.exe in Windows Explorer.
EDIT: Additional information: running from VS, “Start debugging” gives False (ie, the exact result is the same as WE-launch Debug \ prog.exe) and “Start without debugging” True (i.e. Inaccurate the result is the same as WE-launch Release \ prog.exe.
EDIT: Alternate Test Examples with Replaced Literals
These two cases
trace.log( String.Format("a= {0:R} b= {1:R} a<b= {2}", 0.392156869F, 0.392156869F, 0.392156869F < 0.392156869F) ); trace.log( String.Format("a= {0:R} b= {1:R} a<b= {2}", 0.392156869F, (100F / 255F), 0.392156869F < (100F / 255F)) );
discrepancies in the outputs of Debug and Release are not displayed. This case:
trace.log( String.Format("a= {0:R} b= {1:R} a<b= {2}", b.GetPixel(447, 517).GetBrightness(), 0.392156869F, b.GetPixel(447, 517).GetBrightness() < 0.392156869F) );
shows the same mismatch (and inaccuracy in Release) as an initial test case.
EDIT: Hidden Minimal Test Case Demonstrating the Problem
Color c = Color.FromArgb( 255, 100, 100, 100 ); trace.log( String.Format("a= {0} b= {1} a<b= {2}", c.GetBrightness(), 0.392156869F, c.GetBrightness() < 0.392156869F) );
outputs this correct result in Debug \ prog.exe:
a= 0.392156869 b= 0.392156869 a<b= False
but this incorrect result in Release \ prog.exe:
a= 0.392156869 b= 0.392156869 a<b= True
EDIT: Remedies
1) From Peter, answer below:
trace.log( String.Format("a= {0:R} b= {1:R} a<b= {2}", c.GetBrightness(), 0.392156869F, c.GetBrightness().CompareTo(0.392156869F)<0) );
2) From ChrisJJ, questionnaire ( UPDATED ):
float comp = c.GetBrightness(); trace.log( String.Format("a= {0:R} b= {1:R} a<b= {2}", comp, 0.392156869F, comp < 0.392156869F) );
I think this adds evidence of the Release mode compiler error.