I have been trying to implement a binary search on a sorted array of data with an application for cubic spline interpolation. I am unable to get it to function on all the range. For instance, search number 4.4 should return the lower bound 4.35 of range [4.35-4.57). 4.57 lives in both [4.35-4.57] and [4.57, 4.76) etc.
Sub Binary_Search_of_Array()
Dim SplineRanges() As Variant
Dim Right As Integer
Dim Middle As Integer
Dim Left As Integer
Dim SearchNumber As Variant
SplineRanges = Array(4, 4.35, 4.57, 4.76, 5.26, 5.88)
SearchNumber = 4.4
Right = UBound(SplineRanges)
Left = LBound(SplineRanges)
Do While Left < Right
Middle = Left + (Right - Left) / 2
If SplineRanges(Middle) < SearchNumber Then
Left = Middle + 1
ElseIf SplineRanges(Middle) > SearchNumber Then
Right = Middle - 1
Else
Left = Middle
Exit Do
End If
Loop
Debug.Print SplineRanges(Left - 1); SearchNumber; SplineRanges(Left) ' Tried many different statements to return the correct bounds.
End Sub
I was too quick pointing out (only) one thing that was making your code have trouble. I took another look at the over all logic, and came up with the following snippet – which is easier to follow, and correct:
I ran this over the full range of values from 4.01 to 5.88 in steps of 0.01, and it seems to behave itself throughout. The logic is a bit easier to grasp: if your midpoint value is too high, then you adjust your lower boundary to that point; otherwise you adjust your upper boundary. Once the upper and lower boundaries are only one apart, your target is “in the bracket”. Note that floating point types don’t really every reach equality, except for small integer values. So the point that you made about “4.57 lives in both [4.35-4.57] and [4.57-4.76]” is tricky. At any rate, when you are making splines the approximation doesn’t break down when you are “just the wrong side of a point” since splines have all those lovely continuous derivatives…