Public Function IsGoodRound() As Boolean
' verify correct Round returns, 20050614
' returns True if all tests are passed
Dim fFailed As Boolean

' replace "Round17" with the name of your function to test
'
' ! note the differences to VB6's native Round function!

' check half-rounding
If Round17(1.49999999999999) <> 1 Then Stop: fFailed = True
If Round17(1.5) <> 2 Then Stop: fFailed = True
' ! VB6 Round returns 2 ("banker's rounding"):
If Round17(2.5) <> 3 Then Stop: fFailed = True
' ! VB6 Round returns 1.234
If Round17(1.2345, 3) <> 1.235 Then Stop: fFailed = True
' ! VB6 Round returns -1.234
If Round17(-1.2345, 3) <> -1.235 Then Stop: fFailed = True
If Round17(1.2355, 3) <> 1.236 Then Stop: fFailed = True

' 20100601: the bug fixed by Jeroen De Maeijer
If Round17(-0.0714285714, 1) <> -0.1 Then Stop: fFailed = True

' 20060201: Hallman-bug (Round17)
If Round17(0.09, 1) <> 0.1 Then Stop: fFailed = True
If Round17(0.0099, 1) <> 0# Then Stop: fFailed = True
If Round17(0.0099, 2) <> 0.01 Then Stop: fFailed = True
If Round17(0.0099, 3) <> 0.01 Then Stop: fFailed = True
If Round17(0.0099, 4) <> 0.0099 Then Stop: fFailed = True

' check resolution
If NiceDbl(Round17(1.01234012340125, 14)) <> 1.01234012340125 Then Stop: fFailed = True
' ! VB6 Round returns 1.0123401234012
If Round17(1.01234012340125, 13) <> 1.0123401234013 Then Stop: fFailed = True

' check large numbers
If NiceDbl(Round17(10 ^ 13 + 0.74, 1)) <> 10000000000000.7 Then Stop: fFailed = True
' ! VB6 Round returns -9999999999999.2
If Round17(-10 ^ 13 + 0.75, 1) <> -9999999999999.3 Then Stop: fFailed = True
' ! VB6 error 5
If Round17(1.11111111111111E+16, -15) <> 1.1E+16 Then Stop: fFailed = True

' check very large numbers
If Round17(10 ^ 307) <> 1E+307 Then Stop: fFailed = True
If Round17(-10 ^ 308) <> -1E+308 Then Stop: fFailed = True
' check very large decimal places (arbitrary limit set to 20/-20)
If NiceDbl(Round17(10.5, 20)) <> 10.5 Then Stop: fFailed = True
' ! VB6 error 5
If NiceDbl(Round17(10.5, -20)) <> 0 Then Stop: fFailed = True

' check negative numbers (should round, not truncate)
If Round17(-226.6) <> -227 Then Stop: fFailed = True
' ! VB6 Round returns -226
If Round17(-226.5) <> -227 Then Stop: fFailed = True
If Round17(-226.4) <> -226 Then Stop: fFailed = True

' check negative rounding
' ! VB6 Round raises error 5 on all of these:
If Round17(226.7, -1) <> 230 Then Stop: fFailed = True
If Round17(226.7, -2) <> 200 Then Stop: fFailed = True
If Round17(226.7, -3) <> 0 Then Stop: fFailed = True
If Round17(226.7, -4) <> 0 Then Stop: fFailed = True

' check rounding of nasty reals (tnx Gustav Brock!)
' ! VB6 Round fails on all four ("banker's rounding")
' some emulations fail on the first two
If Round17(2.445, 2) <> 2.45 Then Stop: fFailed = True
If Round17(-2.445, 2) <> -2.45 Then Stop: fFailed = True
If Round17(3.445, 2) <> 3.45 Then Stop: fFailed = True
If Round17(-3.445, 2) <> -3.45 Then Stop: fFailed = True
''If Round17(100.05, 1) <> 100.1 Then Stop: fFailed = True
''If Round17(-100.05, 1) <> -100.1 Then Stop: fFailed = True
'
' more nasty reals
' ! VB6 Round totally fails on some of those numbers (!!)
If Round17(30.675, 2) <> 30.68 Then Stop: fFailed = True
If Round17(31.675, 2) <> 31.68 Then Stop: fFailed = True
If Round17(32.675, 2) <> 32.68 Then Stop: fFailed = True 'VB6 Round -> 32.67 !!
If Round17(33.675, 2) <> 33.68 Then Stop: fFailed = True 'VB6 Round -> 33.67 !!
If Round17(128.015, 2) <> 128.02 Then Stop: fFailed = True 'VB6 Round -> 128.01 !!
If Round17(128.045, 2) <> 128.05 Then Stop: fFailed = True 'VB6 Round -> 128.04 Bankers

' 2 times the same
If Round17(1.01010101010101, 2) <> 1.01 Then Stop: fFailed = True
If Round17(1.01010101010101, 2) <> 1.01 Then Stop: fFailed = True

' well done
IsGoodRound = Not fFailed

End Function

Private Function NiceDbl(Dbl As Double) As Double ' helper for IsGoodRound, 20020404 ' Some rounding algorithms return results that need a special ' treatment to cope with subtle floating point errors. For example: ' ? 10 ^ 13 + 0.74 ' -> 10000000000000.7 ' ? Round10(10 ^ 13 + 0.74, 1) ' -> 10000000000000.7 ' BUT: ' ? Round10(10 ^ 13 + 0.74, 1) - 10000000000000.7 ' -> 0.001953125 'and not 0 as you would expect! ' One way to handle this is to wrap the result with Val. ' However, this does not work on systems where where Pi is 3,141... ' and not 3.141..., ie where the decimal sign is not the period ' character ("."): Val() is not such a smart function. ' (Tnx to Gustav Brock for the hint!) ' Another way is this, and it appears to work on all systems. NiceDbl = CDec(Dbl) End Function

Back to Round