Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 589131
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 13, 20262026-05-13T15:23:28+00:00 2026-05-13T15:23:28+00:00

I was writing an instructive example for a colleague to show him why testing

  • 0

I was writing an instructive example for a colleague to show him why testing floats for equality is often a bad idea. The example I went with was adding .1 ten times, and comparing against 1.0 (the one I was shown in my introductory numerical class). I was surprised to find that the two results were equal (code + output).

float @float = 0.0f;
for(int @int = 0; @int < 10; @int += 1)
{
    @float += 0.1f;
}
Console.WriteLine(@float == 1.0f);

Some investigation showed that this result could not be relied upon (much like float equality). The one I found most surprising was that adding code after the other code could change the result of the calculation (code + output). Note that this example has exactly the same code and IL, with one more line of C# appended.

float @float = 0.0f;
for(int @int = 0; @int < 10; @int += 1)
{
    @float += 0.1f;
}
Console.WriteLine(@float == 1.0f);
Console.WriteLine(@float.ToString("G9"));

I know I’m not supposed to use equality on floats and thus shouldn’t care too much about this, but I found it to be quite surprising, as have about everyone I’ve shown this to. Doing stuff after you’ve performed a calculation changes the value of the preceding calculation? I don’t think that’s the model of computation people usually have in their minds.

I’m not totally stumped, it seems safe to assume that there’s some kind of optimization occurring in the “equal” case that changes the result of the calculation (building in debug mode prevents the “equal” case). Apparently, the optimization is abandoned when the CLR finds that it will later need to box the float.

I’ve searched a bit but couldn’t find a reason for this behavior. Can anyone clue me in?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-13T15:23:29+00:00Added an answer on May 13, 2026 at 3:23 pm

    This is a side effect of the way the JIT optimizer works. It does more work if there is less code to generate. The loop in your original snippet gets compiled to this:

                    @float += 0.1f;
    0000000f  fld         dword ptr ds:[0025156Ch]          ; push(intermediate), st0 = 0.1
    00000015  faddp       st(1),st                          ; st0 = st0 + st1
                for (int @int = 0; @int < 10; @int += 1) {
    00000017  inc         eax  
    00000018  cmp         eax,0Ah 
    0000001b  jl          0000000F 
    

    When you add the extra Console.WriteLine() statement, it compiles it to this:

                    @float += 0.1f;
    00000011  fld         dword ptr ds:[00961594h]          ; st0 = 0.1
    00000017  fadd        dword ptr [ebp-8]                 ; st0 = st0 + @float
    0000001a  fstp        dword ptr [ebp-8]                 ; @float = st0
                for (int @int = 0; @int < 10; @int += 1) {
    0000001d  inc         eax  
    0000001e  cmp         eax,0Ah 
    00000021  jl          00000011 
    

    Note the difference at address 15 vs address 17+1a, the first loop keeps the intermediate result in the FPU. The second loop stores it back to the @float local variable. While it stays inside the FPU, the result is calculated with full precision. Storing it back however truncates the intermediate result back to a float, losing lots of bits of precision in the process.

    While unpleasant, I don’t believe this is a bug. The x64 JIT compiler behaves differently yet. You can make your case at connect.microsoft.com

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.