Home Upgrade Search Memberlist Extras Hacker Tools Award Goals Help Wiki Contact

.NET 

Visual Basic: For Loop step problem

Hi guys,

In short I've created a For loop for a program that I'm making in which the loop needs to start from i = 0 and end at i = 1, stepping 0.01 at a time.
As such I wrote this...

Assume the following:
Code
Dim range as integer = 1
Dim a as integer = 5
Dim b as integer = 2
Dim c as integer = 2
Dim funcY(100) as Double 'store all Y values
Dim funcX(100) as Double 'store all X values
(Yes I know these can be written as constants, but they're actually passed into a sub routine. I'm only using dim to demonstrate in this post...
Additionally the funcY and funcX array's are bound to 100 indexes for a reason, it's irrelevant to this problem I'm presenting.)
Code
For i = 0 to range Step 0.01
    Console.WriteLine("i = " & i & ". range = " & range)
    funcY(i) = (a*(Pow(i, 2))+b*i+c)
    funcX(i) = i
    Console.WriteLine(inputFunction & ": x = " & funcX(i) & " y = " & funcY(i))    'NOT FULLY WORKING FOR ALL VALS OF A, B AND C
Next

Some of you may have picked up that this code is to output all the x and y values for a quadratic equation in the form ax^2+bx+c.

So, ideally what would happen is the program finds y for all values of x in the range 0 to 1, stepping by 0.01.
Ultimately the above code provided actually does work, but there's a hiccup. For some reason when I hit i = 0.81 to i = 0.82, the results start to act very strange (see below)

So, with a = 5, b = 2, c = 2 and range = 1, stepping by 0.01 between 0 and range(which is 1 in this case) this is what the program outputs
Focus on when i = 0.81. Infact any value of i > 0.81
Code
With the given equation: y=5x^2+2x+2
i = 0. range = 1
y=5x^2+2x+2: x = 0 y = 2
i = 0.01. range = 1
y=5x^2+2x+2: x = 0.01 y = 2.0205
i = 0.02. range = 1
y=5x^2+2x+2: x = 0.02 y = 2.042
i = 0.03. range = 1
y=5x^2+2x+2: x = 0.03 y = 2.0645
i = 0.04. range = 1
y=5x^2+2x+2: x = 0.04 y = 2.088
i = 0.05. range = 1
y=5x^2+2x+2: x = 0.05 y = 2.1125
i = 0.06. range = 1
y=5x^2+2x+2: x = 0.06 y = 2.138
i = 0.07. range = 1
y=5x^2+2x+2: x = 0.07 y = 2.1645
i = 0.08. range = 1
y=5x^2+2x+2: x = 0.08 y = 2.192
i = 0.09. range = 1
y=5x^2+2x+2: x = 0.09 y = 2.2205
i = 0.1. range = 1
y=5x^2+2x+2: x = 0.1 y = 2.25
i = 0.11. range = 1
y=5x^2+2x+2: x = 0.11 y = 2.2805
i = 0.12. range = 1
y=5x^2+2x+2: x = 0.12 y = 2.312
i = 0.13. range = 1
y=5x^2+2x+2: x = 0.13 y = 2.3445
i = 0.14. range = 1
y=5x^2+2x+2: x = 0.14 y = 2.378
i = 0.15. range = 1
y=5x^2+2x+2: x = 0.15 y = 2.4125
i = 0.16. range = 1
y=5x^2+2x+2: x = 0.16 y = 2.448
i = 0.17. range = 1
y=5x^2+2x+2: x = 0.17 y = 2.4845
i = 0.18. range = 1
y=5x^2+2x+2: x = 0.18 y = 2.522
i = 0.19. range = 1
y=5x^2+2x+2: x = 0.19 y = 2.5605
i = 0.2. range = 1
y=5x^2+2x+2: x = 0.2 y = 2.6
i = 0.21. range = 1
y=5x^2+2x+2: x = 0.21 y = 2.6405
i = 0.22. range = 1
y=5x^2+2x+2: x = 0.22 y = 2.682
i = 0.23. range = 1
y=5x^2+2x+2: x = 0.23 y = 2.7245
i = 0.24. range = 1
y=5x^2+2x+2: x = 0.24 y = 2.768
i = 0.25. range = 1
y=5x^2+2x+2: x = 0.25 y = 2.8125
i = 0.26. range = 1
y=5x^2+2x+2: x = 0.26 y = 2.858
i = 0.27. range = 1
y=5x^2+2x+2: x = 0.27 y = 2.9045
i = 0.28. range = 1
y=5x^2+2x+2: x = 0.28 y = 2.952
i = 0.29. range = 1
y=5x^2+2x+2: x = 0.29 y = 3.0005
i = 0.3. range = 1
y=5x^2+2x+2: x = 0.3 y = 3.05
i = 0.31. range = 1
y=5x^2+2x+2: x = 0.31 y = 3.1005
i = 0.32. range = 1
y=5x^2+2x+2: x = 0.32 y = 3.152
i = 0.33. range = 1
y=5x^2+2x+2: x = 0.33 y = 3.2045
i = 0.34. range = 1
y=5x^2+2x+2: x = 0.34 y = 3.258
i = 0.35. range = 1
y=5x^2+2x+2: x = 0.35 y = 3.3125
i = 0.36. range = 1
y=5x^2+2x+2: x = 0.36 y = 3.368
i = 0.37. range = 1
y=5x^2+2x+2: x = 0.37 y = 3.4245
i = 0.38. range = 1
y=5x^2+2x+2: x = 0.38 y = 3.482
i = 0.39. range = 1
y=5x^2+2x+2: x = 0.39 y = 3.5405
i = 0.4. range = 1
y=5x^2+2x+2: x = 0.4 y = 3.6
i = 0.41. range = 1
y=5x^2+2x+2: x = 0.41 y = 3.6605
i = 0.42. range = 1
y=5x^2+2x+2: x = 0.42 y = 3.722
i = 0.43. range = 1
y=5x^2+2x+2: x = 0.43 y = 3.7845
i = 0.44. range = 1
y=5x^2+2x+2: x = 0.44 y = 3.848
i = 0.45. range = 1
y=5x^2+2x+2: x = 0.45 y = 3.9125
i = 0.46. range = 1
y=5x^2+2x+2: x = 0.46 y = 3.978
i = 0.47. range = 1
y=5x^2+2x+2: x = 0.47 y = 4.0445
i = 0.48. range = 1
y=5x^2+2x+2: x = 0.48 y = 4.112
i = 0.49. range = 1
y=5x^2+2x+2: x = 0.49 y = 4.1805
i = 0.5. range = 1
y=5x^2+2x+2: x = 0.5 y = 4.25
i = 0.51. range = 1
y=5x^2+2x+2: x = 0.51 y = 4.3205
i = 0.52. range = 1
y=5x^2+2x+2: x = 0.52 y = 4.392
i = 0.53. range = 1
y=5x^2+2x+2: x = 0.53 y = 4.4645
i = 0.54. range = 1
y=5x^2+2x+2: x = 0.54 y = 4.538
i = 0.55. range = 1
y=5x^2+2x+2: x = 0.55 y = 4.6125
i = 0.56. range = 1
y=5x^2+2x+2: x = 0.56 y = 4.688
i = 0.57. range = 1
y=5x^2+2x+2: x = 0.57 y = 4.7645
i = 0.58. range = 1
y=5x^2+2x+2: x = 0.58 y = 4.842
i = 0.59. range = 1
y=5x^2+2x+2: x = 0.59 y = 4.9205
i = 0.6. range = 1
y=5x^2+2x+2: x = 0.6 y = 5
i = 0.61. range = 1
y=5x^2+2x+2: x = 0.61 y = 5.0805
i = 0.62. range = 1
y=5x^2+2x+2: x = 0.62 y = 5.162
i = 0.63. range = 1
y=5x^2+2x+2: x = 0.63 y = 5.2445
i = 0.64. range = 1
y=5x^2+2x+2: x = 0.64 y = 5.328
i = 0.65. range = 1
y=5x^2+2x+2: x = 0.65 y = 5.4125
i = 0.66. range = 1
y=5x^2+2x+2: x = 0.66 y = 5.498
i = 0.67. range = 1
y=5x^2+2x+2: x = 0.67 y = 5.5845
i = 0.68. range = 1
y=5x^2+2x+2: x = 0.68 y = 5.672
i = 0.69. range = 1
y=5x^2+2x+2: x = 0.69 y = 5.7605
i = 0.7. range = 1
y=5x^2+2x+2: x = 0.7 y = 5.85
i = 0.71. range = 1
y=5x^2+2x+2: x = 0.71 y = 5.9405
i = 0.72. range = 1
y=5x^2+2x+2: x = 0.72 y = 6.032
i = 0.73. range = 1
y=5x^2+2x+2: x = 0.73 y = 6.1245
i = 0.74. range = 1
y=5x^2+2x+2: x = 0.74 y = 6.218
i = 0.75. range = 1
y=5x^2+2x+2: x = 0.75 y = 6.3125
i = 0.76. range = 1
y=5x^2+2x+2: x = 0.76 y = 6.408
i = 0.77. range = 1
y=5x^2+2x+2: x = 0.77 y = 6.5045
i = 0.78. range = 1
y=5x^2+2x+2: x = 0.78 y = 6.602
i = 0.79. range = 1
y=5x^2+2x+2: x = 0.79 y = 6.70050000000001
i = 0.8. range = 1
y=5x^2+2x+2: x = 0.8 y = 6.8
i = 0.81. range = 1
y=5x^2+2x+2: x = 0.81 y = 6.9005
i = 0.820000000000001. range = 1
y=5x^2+2x+2: x = 0.820000000000001 y = 7.002
i = 0.830000000000001. range = 1
y=5x^2+2x+2: x = 0.830000000000001 y = 7.10450000000001
i = 0.840000000000001. range = 1
y=5x^2+2x+2: x = 0.840000000000001 y = 7.20800000000001
i = 0.850000000000001. range = 1
y=5x^2+2x+2: x = 0.850000000000001 y = 7.31250000000001
i = 0.860000000000001. range = 1
y=5x^2+2x+2: x = 0.860000000000001 y = 7.41800000000001
i = 0.870000000000001. range = 1
y=5x^2+2x+2: x = 0.870000000000001 y = 7.52450000000001
i = 0.880000000000001. range = 1
y=5x^2+2x+2: x = 0.880000000000001 y = 7.63200000000001
i = 0.890000000000001. range = 1
y=5x^2+2x+2: x = 0.890000000000001 y = 7.74050000000001
i = 0.900000000000001. range = 1
y=5x^2+2x+2: x = 0.900000000000001 y = 7.85000000000001
i = 0.910000000000001. range = 1
y=5x^2+2x+2: x = 0.910000000000001 y = 7.96050000000001
i = 0.920000000000001. range = 1
y=5x^2+2x+2: x = 0.920000000000001 y = 8.07200000000001
i = 0.930000000000001. range = 1
y=5x^2+2x+2: x = 0.930000000000001 y = 8.18450000000001
i = 0.940000000000001. range = 1
y=5x^2+2x+2: x = 0.940000000000001 y = 8.29800000000001
i = 0.950000000000001. range = 1
y=5x^2+2x+2: x = 0.950000000000001 y = 8.41250000000001
i = 0.960000000000001. range = 1
y=5x^2+2x+2: x = 0.960000000000001 y = 8.52800000000001
i = 0.970000000000001. range = 1
y=5x^2+2x+2: x = 0.970000000000001 y = 8.64450000000001
i = 0.980000000000001. range = 1
y=5x^2+2x+2: x = 0.980000000000001 y = 8.76200000000001
i = 0.990000000000001. range = 1
y=5x^2+2x+2: x = 0.990000000000001 y = 8.88050000000001

VIEW NEXT POST FOR CONTINUATION

VIEW NEXT POST FOR CONTINUATION

VIEW NEXT POST FOR CONTINUATION



The specific problem shows up here
Code
i = 0.8. range = 1
y=5x^2+2x+2: x = 0.8 y = 6.8
i = 0.81. range = 1
y=5x^2+2x+2: x = 0.81 y = 6.9005
i = 0.820000000000001. range = 1
y=5x^2+2x+2: x = 0.820000000000001 y = 7.002
i = 0.830000000000001. range = 1
y=5x^2+2x+2: x = 0.830000000000001 y = 7.10450000000001
i = 0.840000000000001. range = 1
y=5x^2+2x+2: x = 0.840000000000001 y = 7.20800000000001
i = 0.850000000000001. range = 1
y=5x^2+2x+2: x = 0.850000000000001 y = 7.31250000000001
Why all of a sudden has i gone from 0.81 to 0.820000000000001, with this trend continuing throughout the rest of the values for i.
As you can see this affects my x and y results which is no Bueno.
Of course I could limit the decimal places that i could be, but I'm more interested as to WHY this happens more than anything else.

Any ideas HF?
Tah, Leech
"Floating-point decimal values generally do not have an exact binary representation. This is a side effect of how the CPU represents floating point data. For this reason, you may experience some loss of precision, and some floating-point operations may produce unexpected results."

- https://msdn.microsoft.com/en-us/library/c151dt3s.aspx
As the user above me said, double variables are just ESTIMATIONS. They cant store the exact value.
Thats why the output is correct at the beginning. The error is just too small. But as you keep making more operations, the estimation becomes more and more imprecise.
So how can you avoid this?
The main problem we have here is re-calculating the i value based on the previous value of it. So we are basically estimating a value based on a estimation. We need to get rid of that. We want to calculate (estimate) i based on a true value (integer). (True value = a value that is not estimated)

To do that, replace :
Code
For i = 0 to range Step 0.01
With:
Code
       For k = 0 To Range * 100 Step 1
           Dim i As Double = k * 0.01

Doing this, we re-calculate the i value based on the current k value. (not based on the previous i value).

Your final code will be :
Code
Dim Range As Integer = 1
        Dim a As Integer = 5
        Dim b As Integer = 2
        Dim c As Integer = 2
        Dim funcY(100) As Double 'store all Y values
        Dim funcX(100) As Double 'store all X values
        For k = 0 To Range * 100 Step 1
            Dim i As Double = k * 0.01
            Console.WriteLine("i = " & i & ". range = " & Range)
            funcY(i) = (a * (Pow(i, 2)) + b * i + c)
            funcX(i) = i
            Console.WriteLine(inputFunction & ": x = " & funcX(i) & " y = " & funcY(i))    'NOT FULLY WORKING FOR ALL VALS OF A, B AND C
        Next
Replies are much appreciated.

I guess that makes sense then, to me it was quite weird just to see crop up but now I understand...

(Apr 19, 2018 04:07 AM)SIM-2362662 Wrote:  As the user above me said, double variables are just ESTIMATIONS. They cant store the exact value.
Thats why the output is correct at the beginning. The error is just too small. But as you keep making more operations, the estimation becomes more and more imprecise.
So how can you avoid this?
The main problem we have here is re-calculating the i value based on the previous value of it. So we are basically estimating a value based on a estimation. We need to get rid of that. We want to calculate (estimate) i based on a true value (integer). (True value = a value that is not estimated)

To do that, replace :
Code
For i = 0 to range Step 0.01
With:
Code
       For k = 0 To Range * 100 Step 1
           Dim i As Double = k * 0.01

Doing this, we re-calculate the i value based on the current k value. (not based on the previous i value).

Your final code will be :
Code
Dim Range As Integer = 1
        Dim a As Integer = 5
        Dim b As Integer = 2
        Dim c As Integer = 2
        Dim funcY(100) As Double 'store all Y values
        Dim funcX(100) As Double 'store all X values
        For k = 0 To Range * 100 Step 1
            Dim i As Double = k * 0.01
            Console.WriteLine("i = " & i & ". range = " & Range)
            funcY(i) = (a * (Pow(i, 2)) + b * i + c)
            funcX(i) = i
            Console.WriteLine(inputFunction & ": x = " & funcX(i) & " y = " & funcY(i))    'NOT FULLY WORKING FOR ALL VALS OF A, B AND C
        Next


Yeah, that's the exact method I initially wrote down and thought that I could just use a step of 0.01 instead (to which I stumbled across the double problem). So I actually have this already implemented, though the response is still appreciated.

Many thanks people!
I mean this:
Code
Public Function QuadricEquation(ByVal A As Integer, ByVal B As Integer, ByVal C As Integer, ByVal Range As Single) As Vec2()
        Dim storedAnswers(Decimal.Round(Range, 2, MidpointRounding.AwayFromZero) * 100) As Vec2

        For i As Integer = 0 To Decimal.Round(Range, 2, MidpointRounding.AwayFromZero) * 100

            Dim temp_i As Single = i / 100.0F

            Console.WriteLine("i = " & temp_i & ". range = " & Range)
            storedAnswers(i) = New Vec2(temp_i, (A * (Math.Pow(temp_i, 2)) + B * temp_i + C))
            Console.WriteLine("y=5x^2+2x+2" & ": " & storedAnswers(i).ToString)

        Next
        Console.WriteLine("")
        Console.WriteLine("Quadric equation completed.")
        Console.ReadKey(True)
        Return storedAnswers
    End Function
Gave me this:
Code
'Too many chars to keep whole log
y=5x^2+2x+2: x: 0,65  y:5,4125
i = 0,66. range = 1
y=5x^2+2x+2: x: 0,66  y:5,498
i = 0,67. range = 1
y=5x^2+2x+2: x: 0,67  y:5,5845
i = 0,68. range = 1
y=5x^2+2x+2: x: 0,68  y:5,672
i = 0,69. range = 1
y=5x^2+2x+2: x: 0,69  y:5,7605
i = 0,7. range = 1
y=5x^2+2x+2: x: 0,7  y:5,85
i = 0,71. range = 1
y=5x^2+2x+2: x: 0,71  y:5,9405
i = 0,72. range = 1
y=5x^2+2x+2: x: 0,72  y:6,032
i = 0,73. range = 1
y=5x^2+2x+2: x: 0,73  y:6,1245
i = 0,74. range = 1
y=5x^2+2x+2: x: 0,74  y:6,218
i = 0,75. range = 1
y=5x^2+2x+2: x: 0,75  y:6,3125
i = 0,76. range = 1
y=5x^2+2x+2: x: 0,76  y:6,408
i = 0,77. range = 1
y=5x^2+2x+2: x: 0,77  y:6,5045
i = 0,78. range = 1
y=5x^2+2x+2: x: 0,78  y:6,602
i = 0,79. range = 1
y=5x^2+2x+2: x: 0,79  y:6,7005
i = 0,8. range = 1
y=5x^2+2x+2: x: 0,8  y:6,8
i = 0,81. range = 1
y=5x^2+2x+2: x: 0,81  y:6,9005
i = 0,82. range = 1
y=5x^2+2x+2: x: 0,82  y:7,002
i = 0,83. range = 1
y=5x^2+2x+2: x: 0,83  y:7,1045
i = 0,84. range = 1
y=5x^2+2x+2: x: 0,84  y:7,208
i = 0,85. range = 1
y=5x^2+2x+2: x: 0,85  y:7,3125
i = 0,86. range = 1
y=5x^2+2x+2: x: 0,86  y:7,418
i = 0,87. range = 1
y=5x^2+2x+2: x: 0,87  y:7,5245
i = 0,88. range = 1
y=5x^2+2x+2: x: 0,88  y:7,632
i = 0,89. range = 1
y=5x^2+2x+2: x: 0,89  y:7,7405
i = 0,9. range = 1
y=5x^2+2x+2: x: 0,9  y:7,85
i = 0,91. range = 1
y=5x^2+2x+2: x: 0,91  y:7,9605
i = 0,92. range = 1
y=5x^2+2x+2: x: 0,92  y:8,072001
i = 0,93. range = 1
y=5x^2+2x+2: x: 0,93  y:8,1845
i = 0,94. range = 1
y=5x^2+2x+2: x: 0,94  y:8,298
i = 0,95. range = 1
y=5x^2+2x+2: x: 0,95  y:8,412499
i = 0,96. range = 1
y=5x^2+2x+2: x: 0,96  y:8,528
i = 0,97. range = 1
y=5x^2+2x+2: x: 0,97  y:8,644501
i = 0,98. range = 1
y=5x^2+2x+2: x: 0,98  y:8,762
i = 0,99. range = 1
y=5x^2+2x+2: x: 0,99  y:8,8805
i = 1. range = 1
y=5x^2+2x+2: x: 1  y:9

Quadric equation completed.
If that's what you're looking for.


Possibly Related Threads...
Thread / Author Replies Views Last Post
[Source] by SIM-5420967May 26, 2024 09:50 AM 2 373 May 26, 2024 09:50 AM
Last Post: xiaowanga8
[Python] by johngacySep 19, 2023 09:00 AM 2 238 Sep 19, 2023 09:00 AM
Last Post: johngacy
[.NET] by BladabindiMay 17, 2023 12:20 AM 1 178 May 17, 2023 12:20 AM
Last Post: NyQuil