Your fundamental problem is that you are rounding to the same number of significant figures that you are performing your computations with. However, since rounding takes place at one significant figure higher than that, this means your displayed solution will be impacted by rounding error. To get around that, you merely need to either round to one digit less, or operate at one significant digit more. I assume you can't reduce your displayed digit, so that makes the decision easy:
Code:
txtX = vbNullString
math.StoreExpression lstEqu.Text
For X = xmin To xmax Step 0.0001
Y = math.Eval1(X)
If Y >= CSng(txtY) - 0.0005 And Y <= CSng(txtY) + 0.0005 Then
txtX = CStr(Round(X, 3))
Exit For
End If
Next X
Unfortunately, this adds 10 times as many computations. There are a few ways to address this. Notably, you can clean up the code a little pit by minimizing the processing that take place inside the For loop:
Code:
Dim minY As Single
Dim maxY As Single
minY = CSng(txtY) - 0.0005
maxY = minY + 0.001
txtX = vbNullString
math.StoreExpression lstEqu.Text
For X = xmin To xmax Step 0.0001
Y = math.Eval1(X)
If Y >= minY And Y <= maxY Then
txtX = CStr(Round(X, 3))
Exit For
End If
Next X
But if you really want to make it run faster you need to redesign your approach entirely to use things like binary searches or simulated annealing, and you may need to customize this stuff for non-linear functions.