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 !!
  ' added 20050712
  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