[RESOLVED] Problem with for loop
Hello.
I'm having a problem with my for loop. Below is the code. a, b, c, and d are variables of type Double which have been calculated earlier. I want to find the maximum value of q12. For a particular set of values for a, b, c, and d, the answer is supposed to be maximum at pos_max=0.05. However, the answer produced is at pos_max=0.0499. Why is this so? Any help would be much appreciated.
Code:
Dim i, max, pos_max As Double
max=0
For i = 0 To 0.05 Step 0.0001
q12 = Abs(a * (i ^ 2) + b * i + c * (i ^ 2) + d * i)
If (max < q12) Then
max = q12
pos_max = i 'max position on 1-2
End If
Next
Re: Problem with for loop
Welcome to VBForums :wave:
To start i and max are not declared as Double, they are Variants. For more information, see the article What's wrong with Dim x, y, z As Long ? from our Classic VB FAQs (in the FAQ forum)
As to the issue, that is a common problem in computing when floating-point numbers (in VB6, Single and Double) are being used, because they are designed for speed rather than accuracy - so after a few decimal places you get a bit of creep (usually after about 7 decimal places).
If you want full accuracy then use the Currency data type (or Variant with a sub-type of Decimal), but that will be much slower.
If you just want it accurate to about 3 decimal places then floating-point numbers are fine, you just need to round the result, eg:
Code:
MsgBox Round(max,3)
Re: Problem with for loop
Welcome to VBF.
In your For Loop i is incremented at each time it passes "next". So your i is incremented at last to 0.05 and in that case to loop is stopped. So your pos_max is never set to this last i amount.
EDIT:
My failure, si_the_geek is correct. The problem is caused by not correctly declaring the Doubles. Forget all above
Re: [RESOLVED] Problem with for loop
Thank you si_the_geek and opus! I used Currency data type and it works. =)
Re: [RESOLVED] Problem with for loop
I want pick up on something Si has said. It is often said that floating point numbers are inaccurate this is not really true. The problem lies in that base 10 numbers often do not convert well to base 2 and vice versa. eg 0.001 looks nice in base 10 but it cannot convert exactly to base 2, on the other hand 0.0009765625 looks pretty horrible in base 10 but it converts perfectly to base 2. When a number cannot be expressed exactly in base two there is a small rounding error. In the case of double this rounding error is always less than 0.0000000000000001 * number however the error can be exaggerated if say it was added to itself many times.
There is another thing at play which has to do with prime factors, 10 has two prime factors but 2, 4, 8, 16 etc have only the 1. I can't think of a way of explaining it easily other than converting a rational number from a base with more primary factors than the base it is converted to will often yield an irrational number.
Code:
Dim dp As Double
For dp = 0.0009765625 To 1# - 0.0009765625 Step 0.0009765625
Next
Debug.Print dp '<-- results in exactly 1
For dp = 0.001 To 1# - 0.001 Step 0.001
Next
Debug.Print dp '<-- results in 0.999000000000001
I suppose what I am trying to say is that floating point numbers are fairly accurate (~16 decimal places / 53 binary places, in the case of a double) and have an enormous range but we are used to thinking in base 10 and not base 2.