Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Problems comparing doubles 2

Status
Not open for further replies.

BML

Programmer
Oct 24, 2000
37
0
0
PT
(Sorry about last one - no title...)

Hi,

try to run this code:
Code:
'------------------------------------------
Private Sub Form_Load()

  Dim a As Double
  Dim b As Double

  a = 6.3
  b = 1.1 + 2.1 + 3.1
  
  Debug.Print "a = " & a                'a = 6,3
  Debug.Print "b = " & b                'b = 6,3
  Debug.Print "a = b : " & CBool(a = b) 'a = b : False
  Debug.Print "a - b = " & a - b
                            'a-b= -8,88178419700125E-16

End Sub
'------------------------------------------
and notice that VB doesn't assume that a is equal to b,
can anyone explain why? regards,

Bruno Loureiro.

 
What you are seeing is rounding error. When b is calculated, there is some rounding error that is taking place, that is why you get a-b = -8*10^-16.

To make the error disapear, try this minor modification:

b = round(1.1 + 2.1 + 3.1,1)


and run the code, you'll notice this time that it will work the way that you expect....

Actually you can put 14 inplace of the 1 and it will still work. If I put 15, then it gives the usually results.

AS to why exactly this rounding error occurs, someone else may be able to explain it better then I can as computer arithmatic was not really a strong point of mine.

Regards... Troy Williams B.Eng.
fenris@hotmail.com

 
Hi,

I don't really know if its like this, but since a - b is a number bigger than 0, it means that visual basic has lost its precision. I already knew that double can't have more numbers than 15, they can, but the problem is that it looses its precision, but this doesn't mean that it should 'round' off a number with less than 15 digits shouldn't it? Anyway, a quick and easy way to solve this problem is to change this line:

[tt]Debug.Print "a = b : " & CBool(a = b) 'a = b : False[/tt]

to:

[tt]Debug.Print "a = b : " & CBool(CStr(a) = CStr(b)) 'a = b : True[/tt]

If you want to calculate with bigger numbers than 15 digits and you don't want to loose the precision, you would have to write your own algorithms to handle this. I started on such a thing already and it's working pretty good so far :)

Anyway, I hope this helped you,

LuCkY
 
In the case above, a-b was a really small negative number, indicating that b had some garbage around the 15th decimal place.

The reason that this "error" occured is because of the way the number was obtained, by addition. I imaging that this would happen with any of the other operations.

Now if you are only worried about 3 or four decimal places of accuracy, then you should be using singles, and rounding to the desired number of decimal places. Now if you think that you need 15 or more decimal places, then be prepared to create your own routines.

In my experience, most high precision calculations only require about 6 decimal places, for the simple fact that physical measurements can not be made any more accurate.

Take for instance chemistry, some equipment like measuring flasks are guaranteed to have an accuracy of 2 decimal places, so measurements are recorded to three decimal places and therefore calculations are only done with decimal places. Now if these calcs where done on a computer, you would definately use more decimal places to stave off the rounding errors, but your final results would always be rounded to your least accurate measurement.

Troy Williams B.Eng.
fenris@hotmail.com

 
The problem occurs because one-tenth (0.1) cannot be accurately represented in base-2 arithmetic. I can't get Windows calculator to represent fractional numbers in binary, but if it could, you'd see it as 0.10101010... with the "1010" part repeating.

When you add three of them together, they do not add up to the equivalent of 0.3 due to the repeated rounding errors.

Chip H.
 
Please open the immediate window in a new Visual
Basic Project and enter the following statement
that calculates 1 degree in radians

print atn(1)*4 /180
1.75432925199435E-02
the result displayed is in scientific notation.
the higher weighted numerals will be interpreted
as 1.7

Now try:
print round(atn(1)*4/180,5)
.0174533
this is what you really want.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top