Here's a subroutine I have used with success (probably it will have to be somewhat modified to suit your needs). I'm not sure it works quite "foolproof",I think there's an error with negative numbers...
I am attaching a demo project.
Btw the variables' names are not too explicit as to their meaning, as I'm using an old (with a limited number of characters per variable name) Fortran routine that I converted almost literally.
VB Code:
Public Sub RoundToNearest(zs)
'Given a number zs (of single type), another number is calculated
'of similar order of magnitude but "rounded up to the nearest number
'of a series a(i) or one of their multiples or submultiples
'The numbers a(1), a(2), ... are up to the user's taste
'I have chosen 1, 2 and 5, so that my rounded number
'will be one in the series 1, 2, 5, 10, 20, 50, 100, 200, 500, ...
'or 0.1, 0.2, 0.5, 0.01, 0.02, 0.05, ...
'The result is placed in zs so the original is destroyed
'(i.e. work with a copy)
Dim a(1 To 3) as integer
Dim zs as single
a(1) = 1: a(2) = 2: a(3) = 5
For i = 1 To 3
If zs = a(i) Then Exit Sub
Next
jsign = Sgn(zs - 1)
lex = (jsign - 1) \ 2
f = 10 ^ lex
Start:
For k = 1 To 3
kk = k + 1
ff = f
If k = 3 Then
kk = 1
ff = 10 * ff
End If
a1 = a(k) * f
a2 = a(kk) * ff
If zs < a1 Or zs > a2 Then GoTo Endloop
If zs = a1 Or zs = a2 Then Exit Sub
d1 = Abs(zs - a1)
d2 = Abs(zs - a2)
zs = a2
If d1 < d2 Then zs = a1
Exit Sub
Endloop:
Next
f = f * 10 ^ jsign
GoTo Start
End Sub
Last edited by krtxmrtz; Dec 2nd, 2002 at 08:56 AM.
Function MagnitudeRound(dNumber As Double, Optional bRoundUp As Boolean = True, Optional nOrder As Variant) As Double
Dim dOrder As Double
Dim dMantissa As Double
If IsMissing(nOrder) Then
nOrder = Int(Log(dNumber) / Log(10#))
End If
dOrder = 10 ^ nOrder
dMantissa = dNumber / dOrder
If (bRoundUp) Then
MagnitudeRound = Ceil(dMantissa) * dOrder
Else
MagnitudeRound = Floor(dMantissa) * dOrder
End If
End Function
Function Ceil(x As Double) As Double
If Round(x) = x Then
Ceil = x
Else
Ceil = Round(x + 0.5)
End If
End Function
Function Floor(x As Double) As Double
If Round(x) = x Then
Floor = x
Else
Floor = Round(x - 0.5)
End If
End Function
Great code, but not relevant here.. the min value should round to the same order of magnitude of the max value
max =5637 should round to 6000 - fine
min = 134 should round to 0 - yours would round this to 100