Jump to content
Xtreme .Net Talk

Math/Convert Bug in .NET? - present on other machines?


Recommended Posts

Posted

I get the following bug and use the below work around:

 

Have 4 text boxes with the following numbers, I have to keep numbers and total at the 100th's precision, so these are valid inputs:

 

99.69, 0.05, 0.21, 0.05

 

Total the four in a loop as so:

 

(Pseudo code - important part is just the loop)

Dim total as Double

For i as Integer = 0 to Me.txtBoxesCollection.Count - 1

total += Convert.ToDouble(Me.txtBoxesCollection(i).Text)

Next i

 

I end up with 99.999999987 or something weird like that - don't know why. I get this. If I change my code to force the round it works fine - problem is that the 0.21 when added to the total acts more like 0.2000000009???? It's weird

 

Work around:

total = Math.Round(total + Convert.ToDouble(Me.txtBoxesCollection(i).Text, 2)

 

None of my numbers are outside of the 100ths place so I don't understand why I would need to round to the 100ths place - a calculator doesn't result in any numbers going beyond the 100ths place when doing this calculation...

 

Does anyone know what could be causing this?

  • *Experts*
Posted
Internal floating point math is not entirely precise like that, so you will probably need to round off some numbers to get the desired result.
  • Leaders
Posted
This is not a bug specific to .Net, either. This is floating point math with computers, period. You will sometimes find your results off by one or two in the least signifigant digit. Sometimes it makes your numbers look ugly (69.99999999 instead of 70) but in mathematical terms the roundoff error isn't particularly signifigant. You might find that your results will be better if you use the Decimal data type (and you might not). You might also want to use one of the Double.ToString to format your number to round off so something close will appear correctly (99.99999 will round to 100.00).
[sIGPIC]e[/sIGPIC]
Posted
Okay, but I don't understand why it will take 96.74 and add 0.21 and get 98.94999999991 - that may not be exactly what I have above, but it's the point - in the watch window I have those two numbers - so how does this happen? It seems to me having to round the result of 0.07 + 0.81 to decimal places is just a waste of code and gives the 'appearance' of a coder who doesn't know what he's doing in reality he's just trying to get past this 'floating-point' math problem.
Posted

Well, thats just the nature of using a digital computer to solve mathematical problems, doesnt matter how long the mantissa is, it's just the fact that its finite.

 

The reason that you get the correct answer on a calculator, but not if you do 64 bit floating point precision mathematics in a computer (Type Double in VB.NET), is actually due to the LACK of precision in the calculator, not BETTER precision in the calculator.

  • *Experts*
Posted

Have you tried the decimal datatype?

 

I did a quick test in C# Express Beta (a bit older - early summer), which uses .NET 2.0 beta, and could not repro your results. I used your values stored as strings with Convert.ToDouble(), added the results the same as you into a new double variable. In everything I tried, I got back 100.0.

 

I tried with decimal and double. The only real difference is that I didn't use a textbox array, but used strings instead. I can post my code tomorrow if it helps. In any case, I've seen "rounding" issues with double values and can't remember offhand if double was better, or decimal. I think decimal was better suited to these "currency" related issues than double, but I may have that reversed. Maybe try going back to VB6 which had a Currency type :)

 

-nerseus

"I want to stand as close to the edge as I can without going over. Out on the edge you see all the kinds of things you can't see from the center." - Kurt Vonnegut
Posted
This is not a bug specific to .Net' date=' either. This is floating point math with computers, period. You will sometimes find your results off by one or two in the least signifigant digit. Sometimes it makes your numbers look ugly (69.99999999 instead of 70) but in mathematical terms the roundoff error isn't particularly signifigant.[/quote']

 

I thought it was even worse than just being inaccurate, the amount of inaccuracy was dependent on the CPU used (not just brand amd/intel, but actual model as well). I always believed the floating point bug that was in the early versions of the original Pentium was related to this where the inaccuracy was large enough to become significant.

 

This inaccuracy is also why you should never directly compare 2 floats. For instance:

dim fl1 as float = 4

dim fl2 as float = 16

if (fl1 * 2) = (fl2 / 2) then

MessageBox.Show("They are equal")

end if

4 x 2 = 8 and 16 / 2 = 8, so that messagebox should be shown if floats behaved. However I give you a 75% change you wont get that messagebox as floats are to inaccurate to use absolute precision. (hope the code makes sense, my vb is a bit rusty ;) )

 

 

If you are always working on 2 digits you can use another workaround. Instead of working with floats and trying to get rid of the inaccuracy, you can internally use an int/long and divide it by 100 when it needs to be displayed / multiply it by 100 when read from the user interface. This would require some work if you have an extensive algorithm, but it would get rid of the inaccuracy.

Nothing is as illusive as 'the last bug'.
Posted

As a brief background, it is because all numbers are stored in binary form. With integers, its not actually a problem, but when you start getting to decimals, representing them in binary becomes more and more difficult.

 

A highly simplified example would be something like:

 

7.5 = 0111.1 (working in binary, the .1 = (1 * 2 ^ -1) = (1 / 2) = 0.5)

 

So basically, as you move to the right after the decimal point, the digits represent: 1/2, 1/4, 1/8, 1/16 etc. etc.

 

So, to create any decimal, you need it to be represented as a combination of fractions.

 

The more binary significant digits that you use, the more accurate your answer will be, but for some numbers, it will NEVER be exact. Although the computer will actually approximate the correct answer in most cases, when you come to add/subtract/multiply or divide then this is where inconsistencies are likely to appear.

 

See, I knew my college Comp Sci course (where I spent four weeks working with binary on paper.. ugh!) had a use!

 

B.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...