-
May 10th, 2011, 03:58 PM
#1
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
-
May 10th, 2011, 04:02 PM
#2
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.
-
May 10th, 2011, 05:23 PM
#3
Re: Adding doubles together produces different results in Release vs. Debug mode.
Originally Posted by gageller
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
-
May 11th, 2011, 08:16 AM
#4
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
-
May 11th, 2011, 08:32 AM
#5
Re: Adding doubles together produces different results in Release vs. Debug mode.
Originally Posted by gageller
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...
-
May 11th, 2011, 08:59 AM
#6
Re: Adding doubles together produces different results in Release vs. Debug mode.
Originally Posted by gageller
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.
-
May 11th, 2011, 09:03 AM
#7
Re: Adding doubles together produces different results in Release vs. Debug mode.
I did the rounding after adding up the individual parts
-
May 11th, 2011, 09:08 AM
#8
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.
-
May 11th, 2011, 09:24 AM
#9
Re: Adding doubles together produces different results in Release vs. Debug mode.
Originally Posted by Lindley
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
-
May 11th, 2011, 09:33 AM
#10
Re: Adding doubles together produces different results in Release vs. Debug mode.
Originally Posted by gageller
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...
-
May 11th, 2011, 09:40 AM
#11
Re: Adding doubles together produces different results in Release vs. Debug mode.
Thanks everyone.
I appreciate all of the replies!
-
May 11th, 2011, 10:00 AM
#12
Re: Adding doubles together produces different results in Release vs. Debug mode.
Originally Posted by gageller
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
-
May 11th, 2011, 01:04 PM
#13
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.
-
May 11th, 2011, 01:08 PM
#14
Re: Adding doubles together produces different results in Release vs. Debug mode.
Thanks Ahmd,
I'll give it a try.
-
May 11th, 2011, 01:15 PM
#15
Re: Adding doubles together produces different results in Release vs. Debug mode.
Originally Posted by ahmd
...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...
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|