Public Function Round17(ByVal v As Double, Optional ByVal lngDecimals As Long = 0) As Double
' By Filipe Lage
' fclage@gmail.com
' msn: fclage@clix.pt
' Revision C by Donald - 20060201 - (Bugfix)
' Revision D by Jeroen De Maeijer - 20100529 - (Bugfix)
' Revision E by Filipe Lage - 20100530 (speed improvements)
Dim xint As Double, yint As Double, xrest As Double
Static PreviousValue As Double
Static PreviousDecimals As Long
Static PreviousOutput As Double
Static M As Double
If PreviousValue = v And PreviousDecimals = lngDecimals Then Round17 = PreviousOutput: Exit Function
' Hey... it's the same number and decimals as before...
' So, the actual result is the same. No need to recalc it
If v = 0 Then Exit Function
' no matter what rounding is made, 0 is always rounded to 0
If PreviousDecimals = lngDecimals Then
' 20100530 Improvement by fclage - Moved M initialization here for speedup
If M = 0 Then M = 1 ' Initialization - M is never 0 (it is always 10 ^ n)
Else
' A different number of decimal places, means a new Multiplier
PreviousDecimals = lngDecimals
M = 10 ^ lngDecimals
End If
If M = 1 Then xint = v Else xint = v * CDec(M)
' Let's consider the multiplication of the number by the multiplier
' Bug fixed: If you just multiplied the value by M, those nasty reals came up
' So, we use CDEC(m) to avoid that
Round17 = Fix(xint)
' The real integer of the number (unlike INT, FIX reports the actual number)
' 20060201: fix by Donald
If Abs(Fix(10 * (xint - Round17))) > 4 Then
If xint < 0 Then '20100529 fix by Zoenie:
' previous code would round -0,0714285714 with 1 decimal in the end result to 0.1 !!!
' 20100530 Speed improvement by Filipe - comparing vars with < instead of >=
Round17 = Round17 - 1
Else
Round17 = Round17 + 1
End If
End If
' First decimal is 5 or bigger ? If so, we'll add +1 or -1 to the result (later to be divided by M)
If M = 1 Then Else Round17 = Round17 / M
' Divides by the multiplier. But we only need to divide if M isn't 1
PreviousOutput = Round17
PreviousValue = v
' Let's save this last result in memory... may be handy ;)
End Function
|