Fun with Floating Point Arithmetic, Part Fourhttp://blogs.msdn.com/b/ericlippert/archive/2005/01/18/fun-with-floating-point-arithmetic-part-four.aspxA reader also asked the other day why it is that in VBScript, CSng(0.1) = CDbl(0.1) is False . Forget about binary floating point for a moment. Suppose that we had two fixed-point decimal systems, say one with five digits after the decimal place and oneen-USTelligent Evolution Platform Developer Build (Build: 5.6.50428.7875)re: Fun with Floating Point Arithmetic, Part Fourhttp://blogs.msdn.com/b/ericlippert/archive/2005/01/18/fun-with-floating-point-arithmetic-part-four.aspx#2286937Thu, 26 Apr 2007 17:24:33 GMT91d46819-8472-40ad-a661-2c78acb4018c:2286937Sandeep<p>This is for Dave...</p>
<p> A BIG THANKS!!</p>
<p>i just multiplied by 100 ( i had only 2 decimal places) and it solved my issue.</p>
<p>my code was something like this:</p>
<p>If pctTotal > 100 then</p>
<p>... </p>
<p>Response.Write("Percentage total cannot be greater than 100. Your percentage total is " & pctTotal )</p>
<p>...</p>
<p>End If</p>
<p>I was stumped when I got the message like this:</p>
<p>Percentage total cannot be greater than 100. Your percentage total is 100</p>
<p>i just changed into If CInt(pctTotal*100))>10000</p>
<p>Now its all fixed. Thanks guys!</p>
<div style="clear:both;"></div><img src="http://blogs.msdn.com/aggbug.aspx?PostID=2286937" width="1" height="1">re: Fun with Floating Point Arithmetic, Part Fourhttp://blogs.msdn.com/b/ericlippert/archive/2005/01/18/fun-with-floating-point-arithmetic-part-four.aspx#551358Tue, 14 Mar 2006 20:51:58 GMT91d46819-8472-40ad-a661-2c78acb4018c:551358Joe public static double roundnum(double num, int place)
<br> {
<br> double n;
<br> n = num * Math.Pow(10, place);
<br> n = Math.Sign(n) * Math.Abs(Math.Floor(n + .5));
<br> return n / Math.Pow(10, place);
<br> }
<br>
<br>
<br>
<br>didn't write this....but looking for comments on it<div style="clear:both;"></div><img src="http://blogs.msdn.com/aggbug.aspx?PostID=551358" width="1" height="1">re: Fun with Floating Point Arithmetic, Part Fourhttp://blogs.msdn.com/b/ericlippert/archive/2005/01/18/fun-with-floating-point-arithmetic-part-four.aspx#355690Wed, 19 Jan 2005 02:12:00 GMT91d46819-8472-40ad-a661-2c78acb4018c:355690Norman Diamond> The Visual Basic designers decided that loss
<br>> of information is worse than manufacturing
<br>> new information and applied that rule
<br>> consistently to the variant arithmetic logic.
<br>
<br>Except when printing. See your previous blog entry ^_^
<br>
<br>1/18/2005 4:29 PM James Mastros (theorbtwo)
<br>
<br>> when dealing with money, it's often an error
<br>> to carry any more information that the
<br>> smallest unit in the currency
<br>
<br>Surely not. If interest is compounded daily and every 6 months you're supposed to pay the amount of interest that has accrued during those 6 months, you shouldn't compute each day's interest as zero and add up all those zeroes. You need to compute with enough extra digits to make the final result accurate within one of those smallest units, and then round once. (And of course you probably shouldn't be using floating point for any part of this.)<div style="clear:both;"></div><img src="http://blogs.msdn.com/aggbug.aspx?PostID=355690" width="1" height="1">re: Fun with Floating Point Arithmetic, Part Fourhttp://blogs.msdn.com/b/ericlippert/archive/2005/01/18/fun-with-floating-point-arithmetic-part-four.aspx#355624Wed, 19 Jan 2005 00:29:00 GMT91d46819-8472-40ad-a661-2c78acb4018c:355624James Mastros (theorbtwo)As a matter of fact, when dealing with money, it's often an error to carry any more information that the smallest unit in the currency you're dealing with (for the USD, EUR, and GBP, that's 1/100, but it is 1/1000, or 1/1 in some currencies). For example, even if the formulae for a morgtage say that the lendee should pay $1.001 per month, that isn't possible. Instead, they would pay exactly $1.00. That sort of error, when compounded over 40 years, can become noticible.
<br>
<br>I once, a long time ago, wrote a customer tracking system that did 6% tax calculations, and automatically assessed late fees. It was not until it was in production and started assessing late fees to people who showed up as owing "$0.00" and a significant amount of head-scratching did we figure out that some people ended up owing fractional cents. (Of course, if I were writing the system today, I would have done more tests before putting it into production.)<div style="clear:both;"></div><img src="http://blogs.msdn.com/aggbug.aspx?PostID=355624" width="1" height="1">re: Fun with Floating Point Arithmetic, Part Fourhttp://blogs.msdn.com/b/ericlippert/archive/2005/01/18/fun-with-floating-point-arithmetic-part-four.aspx#355478Tue, 18 Jan 2005 21:30:00 GMT91d46819-8472-40ad-a661-2c78acb4018c:355478Eric LippertYes, the "decimal" type in .NET is a base-ten floating point number. It's a 96 bit integer scaled by 10^exp, where exp is any value from 0 to -28.
<br><div style="clear:both;"></div><img src="http://blogs.msdn.com/aggbug.aspx?PostID=355478" width="1" height="1">re: Fun with Floating Point Arithmetic, Part Fourhttp://blogs.msdn.com/b/ericlippert/archive/2005/01/18/fun-with-floating-point-arithmetic-part-four.aspx#355451Tue, 18 Jan 2005 21:04:00 GMT91d46819-8472-40ad-a661-2c78acb4018c:355451Dave BacherOh and that goes for any time you care about significance in any computer math -- never use a single or a double if you care about how many digits come after the decimal.<div style="clear:both;"></div><img src="http://blogs.msdn.com/aggbug.aspx?PostID=355451" width="1" height="1">re: Fun with Floating Point Arithmetic, Part Fourhttp://blogs.msdn.com/b/ericlippert/archive/2005/01/18/fun-with-floating-point-arithmetic-part-four.aspx#355450Tue, 18 Jan 2005 21:03:00 GMT91d46819-8472-40ad-a661-2c78acb4018c:355450Dave BacherIn general, if you're dealing with money, the correct way is to use an integer multilpied by a scaling factor, instead of an IEEE float of any variety (single or double).
<br>
<br>The most common case where you see this problem is when someone's dealing with currency -- it hits double precision inaccuracies a lot, and the runtime tries to compensate for it.
<br>
<br>By using fixed point math (multiply the values by 1000, for example, then divide and convert into a float/double once your done), you eliminate any rounding errors, etc. at the expense of a small increase in the amount of code that you have to write.
<br>
<br>SQL Server, Oracle and ISO C++ provide mechanisms for handling this. I believe the .NET runtime has support for it as well.<div style="clear:both;"></div><img src="http://blogs.msdn.com/aggbug.aspx?PostID=355450" width="1" height="1">