CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 23
  1. #1
    Join Date
    Sep 2003
    Posts
    73

    Adding doubles together produces different results in Release vs. Debug mode.

    Hi All,

    I am running into a problem when adding together three doubles. The result I get when running in Debug mode does not match what I get in Release mode.

    The three parts have the same value in both modes
    dPart1 = 1237.8599999999999
    dPart2 = 2351.9300000000003
    dPart3 = 5407.3799999999992

    When I add the three parts together in Debug Mode I get
    8997.1699999999983

    When I add the three parts together in Release Mode I get
    8997.1700000000001

    The Release Mode value is incorrect and is causing the application to display a value that is one penny too much.

    I'm not sure what is causing this to happen.

    If anyone has any ideas please let me know.

    Thanks so much.

    Greg

  2. #2
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    Re: Adding doubles together produces different results in Release vs. Debug mode.

    Floating point math is not exact, and should not be relied upon for financial computations.

    That isn't to say it's not accurate. It will in most cases give you an answer which is very, very close to correct. However, you can't rely on exactness.

    causing the application to display a value that is one penny too much
    That seems unlikely, since the two values are within $0.00000000001 of each other. More likely, the amount shown for Debug is 1 penny too low, since you probably just truncated the value rather than rounding it.

  3. #3
    Join Date
    Apr 1999
    Posts
    27,449

    Re: Adding doubles together produces different results in Release vs. Debug mode.

    Quote Originally Posted by gageller View Post
    The Release Mode value is incorrect and is causing the application to display a value that is one penny too much.
    As Lindley pointed out, you shouldn't do financial calcualtions using doubles.

    As a matter of fact, in most financial based companies (and I believe, some countries), you can't use floating point for any financial calculations due to round-off error and inexactness (and possible legal action if the calculations lead to short-changing some individual).

    Regards,

    Paul McKenzie

  4. #4
    Join Date
    Sep 2003
    Posts
    73

    Re: Adding doubles together produces different results in Release vs. Debug mode.

    I work for an insurance company. We have an online quoting facility for agents to use to give potential customers a quote.

    We have a disclaimer on the reports stating the total quote is not guaranteed. The problem is that the individual pieces do not add up to make the total quote.

    After doing the calculation manually, it has been determined that the release mode value is one penny too high. One step is rounding up instead of down.

    I do understand what you are saying about the accuracy of the floating point calculations, but still need to provide them with a fix to this problem.

    Would it be better to use floats instead of doubles?

    Thanks again for your help,

    Greg

  5. #5
    Join Date
    Aug 2000
    Location
    New York, NY, USA
    Posts
    5,656

    Re: Adding doubles together produces different results in Release vs. Debug mode.

    Quote Originally Posted by gageller View Post
    Would it be better to use floats instead of doubles?
    No, floats have significantly lower precision compared to doubles.
    Financial industry must have a very strict and very well defined rules for handling fractions, rounding, etc.
    To answer your original question about why debug results are different from release, I guess that floating-point control word is set differently for some reason in these configurations.
    You can explicitly set it yourself to ensure that at least both configurations provide consistent result. Then you can implement proper rounding rules.
    Check out _control87, particularly _MCW_RC (Rounding control).
    Vlad - MS MVP [2007 - 2012] - www.FeinSoftware.com
    Convenience and productivity tools for Microsoft Visual Studio:
    FeinWindows - replacement windows manager for Visual Studio, and more...

  6. #6
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    Re: Adding doubles together produces different results in Release vs. Debug mode.

    Quote Originally Posted by gageller View Post
    After doing the calculation manually, it has been determined that the release mode value is one penny too high.
    Okay, but then you must not have been using the numbers given. Because adding these up:

    dPart1 = 1237.8599999999999
    dPart2 = 2351.9300000000003
    dPart3 = 5407.3799999999992

    is best approximated by adding 1237.86 + 2351.93 + 5407.38 = 8997.17.

    Especially since (in mathematics, not in floating point in particular), 0.99999 (repeating forever) is equal to 1. Not approximately the same; it's exactly 1 and you can prove that. An intuitive but informal outline of the proof is to look at the decimal patterns representing 4/9, 5/9, 7/9, etc, and then consider what 9/9 would look like.
    Last edited by Lindley; May 11th, 2011 at 09:01 AM.

  7. #7
    Join Date
    Sep 2003
    Posts
    73

    Re: Adding doubles together produces different results in Release vs. Debug mode.

    I did the rounding after adding up the individual parts

  8. #8
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    Re: Adding doubles together produces different results in Release vs. Debug mode.

    Doesn't matter. Those three values still add up to be a lot closer to 8997.17 than 8997.16, and both the Debug and Release results you posted above are telling you that.

  9. #9
    Join Date
    Aug 2000
    Location
    West Virginia
    Posts
    7,721

    Re: Adding doubles together produces different results in Release vs. Debug mode.

    Quote Originally Posted by Lindley View Post


    Especially since (in mathematics, not in floating point in particular), 0.99999 (repeating forever) is equal to 1. Not approximately the same; it's exactly 1 and you can prove that. An intuitive but informal outline of the proof is to look at the decimal patterns representing 4/9, 5/9, 7/9, etc, and then consider what 9/9 would look like.
    Off topic, but the proof is even simpler:

    Let x = 0.99999 (repeated forever)

    then 10x = 9.99999 (repeated forever)

    10x - x = 9

    9x = 9

    x = 1

  10. #10
    Join Date
    Aug 2000
    Location
    New York, NY, USA
    Posts
    5,656

    Re: Adding doubles together produces different results in Release vs. Debug mode.

    Quote Originally Posted by gageller View Post
    When I add the three parts together in Debug Mode I get
    8997.1699999999983

    When I add the three parts together in Release Mode I get
    8997.1700000000001

    The Release Mode value is incorrect and is causing the application to display a value that is one penny too much.
    As Lindley pointed above, both of these values should be displayed as 8997.17, so your problem is in formatting the output.
    Vlad - MS MVP [2007 - 2012] - www.FeinSoftware.com
    Convenience and productivity tools for Microsoft Visual Studio:
    FeinWindows - replacement windows manager for Visual Studio, and more...

  11. #11
    Join Date
    Sep 2003
    Posts
    73

    Re: Adding doubles together produces different results in Release vs. Debug mode.

    Thanks everyone.

    I appreciate all of the replies!

  12. #12
    Join Date
    Apr 1999
    Posts
    27,449

    Re: Adding doubles together produces different results in Release vs. Debug mode.

    Quote Originally Posted by gageller View Post
    I do understand what you are saying about the accuracy of the floating point calculations, but still need to provide them with a fix to this problem.
    Long term solution -- use a library specially made for financial (or exact math) calculations. Googling will reveal some of these libraries, plus more information on this entire topic.

    Regards,

    Paul McKenzie

  13. #13
    Join Date
    Feb 2009
    Location
    Portland, OR
    Posts
    1,488

    Re: Adding doubles together produces different results in Release vs. Debug mode.

    As someone pointed out already, the precision of the calculations should be defined by the company's policy. I once coded a program for a company that required a 3-digit fractional precision on their financial calculations. This seems to be a norm for most smaller banks these days (I check my statement from my bank and there's always a variation in a penny -- plus or minus -- from my own financial program.) This stuff, I believe is outlined in all that small print that one has to sign before acknowledging the contract, etc.

    Now going back to the technical aspect, my solution was to write a small rounding method that could be called by default every time that you had to output a result for a user (on a screen or on paper). Something like this:
    Code:
    void printAmountForAUser(double fAmt)
    {
    	//For a 3-digit precision
    	__int64 ulAmt = (__int64)(fAmt * 1000.0);
    	double fAmtRounded = (double)ulAmt / 1000.0;
    	_tprintf(_T("%.2f"), fAmtRounded);
    }
    The important part is to do this "rounding" only on the final result that you output for a human being for viewing, and not on the actual foat/double value that you store back into a database or use for further calculations. This way you will not lose precision of your overall calculations.
    Last edited by ahmd; May 11th, 2011 at 01:08 PM.

  14. #14
    Join Date
    Sep 2003
    Posts
    73

    Re: Adding doubles together produces different results in Release vs. Debug mode.

    Thanks Ahmd,

    I'll give it a try.

  15. #15
    Join Date
    Aug 2000
    Location
    New York, NY, USA
    Posts
    5,656

    Re: Adding doubles together produces different results in Release vs. Debug mode.

    Quote Originally Posted by ahmd View Post
    ...my solution was to write a small rounding method that could be called by default every time that you had to output a result for a user (on a screen or on paper). Something like this:
    Code:
    void printAmountForAUser(double fAmt)
    {
    	//For a 3-digit precision
    	__int64 ulAmt = (__int64)(fAmt * 1000.0);
    	double fAmtRounded = (double)ulAmt / 1000.0;
    	_tprintf(_T("%.2f"), fAmtRounded);
    }
    Sorry, but I don't see any rounding here.
    First you truncate everything past 3-rd decimal place, then you truncate one more while formatting it.
    What was the point of this code? Ans how it differs from:
    Code:
    _tprintf(_T("%.2f"), fAmt);
    Vlad - MS MVP [2007 - 2012] - www.FeinSoftware.com
    Convenience and productivity tools for Microsoft Visual Studio:
    FeinWindows - replacement windows manager for Visual Studio, and more...

Page 1 of 2 12 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured