float datatype gives different result for debug/release build. Bug?

Hi,

Not a question, but more of a discovery that I made.

Basically, I had some code which worked fine on Framework 1.0/1.1, and since porting to 2.0, it has slowed down massively. This is all due to the way floats are dealt with.

If you create a new console application, and paste in the following code. This is just example code, where I've managed to reproduce this strange behaviour outside of my main code.

float low=7f;
float high=100f;
low=((high+low)/2f);
low=((high+low)/2f);
low=((int)(low*100f))/100f;
low=((high+low)/2f);
low=((int)(low*100f))/100f;
low=((high+low)/2f);
low=((int)(low*100f))/100f;
low=((high+low)/2f);
low=((int)(low*100f))/100f;
Console.WriteLine(low);
Console.ReadLine();

Compile this without any debugging information (project properties Build->Advanced...->Debug info=none)

Run this within the IDE, and it returns 97.08, however, if you run the exe from the directory, it returns 97.09

If you compile with debugging information, and run it from the directory, it returns 97.08.

I could understand this if it was just different between different versions of the framework, but this gives different results depending on whether you include debugging information.



Answer this question

float datatype gives different result for debug/release build. Bug?

  • Dasher

    In my code, I'm populating a grid with text, each cell in the grid can have its own font / size / colour etc... so, when I draw the text in the cell, I try to find the biggest font size that will fit all the text in the cell. I do this by using a combination of 'Graphics.Measurestring' and a higher/lower algorithm.

    For example, the min font size is 8, and the max is 10, and the optimum font size is 9.75 (which I don't know at the start).

    I start with 10 - if that fits, I use 10

    if not, I try midway between the last successful low number, and the highest size that doesn't fit, so it goes something like...

    10 (no fit)
    9 FIT (8+10/2)
    9.5 FIT (9+10/2)
    9.75 FIT (9.5+10/2)
    9.875 NOFIT (9.75+10/2)
    ...

    after a few more itterations, it realises that 9.75 was the best.

    However, without debugging information, the loop was endless, and it relied upon my loop count of 1000 before it exited, which meant that what usually takes between 5-10 itterations was always taking 1000.

    In my original code, I was comparing two floats, which were both 9.75, for example, but the == comparison wasn't matching them. I changed it to f1.Equals(f2) and it started working again.


  • Chris398472934

    I have validated it. Hopefully you'll get a response soon.

    How come you experienced perfomance problems because of this



  • Kazi

    When is this done You might improve performance by suspending layout.

    http://msdn2.microsoft.com/en-US/library/system.windows.forms.control.suspendlayout.aspx

    Don't foreget to call ResumeLayout().



  • Yetii

    It got resolved as by design in product feedback center. I do not agree. I posted this as a comment.

    I know floating point are not meant as exact mathematics. What I do not get is the difference between debug/release builds.

    I had the expectation that a floating point calculation would result in the same end result but it might not be exact like 10/2 = 5 but it actually will be 4.99999999999999999999999999999999999993 or something like that.

    Shouldn't the instructions be identical between release/build and generate the same result



  • X-Evolutionist

    I sent a mail to Martyn Lovell that responded to the entry in product feedback center, his response got me to check out what happens in the C++ compiler with your piece of code.

    He mentioned the compiler flags /fp:strict, /fp:precise and /fp:fast. strict and precise deliver the same results as a non-optimized C# build, /fp:fast the same as the release build.

    I can not find any reference to this behaviour but I assume the Optimize flag affects the .NET JIT and will do same optimizations as the C++ compiler does when /fp:fast is enabled when Optimize=true.



  • funky81

  • DWB007

    If you want you can send me a mail with parts of the code that are now taking longer time than before.

    I will have a look and see if it anything I can imagine that will decrease the performance.

    My mail is afjohansson(at)hotmail.com
    Replase (at) with @



  • more FAQ

    I just verified this with VS 2003.NET and VS 2005.

    For debug it is always 97,08 and for release it is 97,09. There is no difference between the versions, just between type of builds.

    I searched the product feedback center and google for some keywords but I found nothing. Even though float is an approximate data type I see no reason that it should give different results between debug and release builds.

    You can add it to the product feedback center. If you post the link to the bug in PFC I will validate it.

    http://lab.msdn.microsoft.com/productfeedback



  • dblythe

    Thanks for the offer, but it is running fine now, as it always has. The reason it was causing a problem was due to this float calculation difference, so I've slightly changed the way it works, and it is now fine on both 'compiles' - albeit slightly differently.

    Rich


  • 69er

    It is done to an offscreen bitmap, but at that stage nothing is actually being drawn.. it's just measuring to find the best size.
  • float datatype gives different result for debug/release build. Bug?