vba mod function floating point number

'VBA does have the 'Mod' operator:
 
MsgBox 5 Mod 2		   	'<--displays: 1   (5 ÷ 2 has a REMAINDER of 1)
  
'But bear in mind that it returns an integer value... always. 

MsgBox 11.5 Mod 3	   	'<--displays: 0   (But it should be 2.5)

'And in some cases it fails completely:

MsgBox 11 Mod 0.4	   	'<--Fails: Runtime error 11: division by zero

'It also does not always handle negative numbers correctly:

MsgBox -11 Mod 3	   	'<--displays: -2  (But it should be 1)
MsgBox 11 Mod -3	   	'<--displays:  2  (But it should be -1)

'The VBA 'Mod' operator also imposes limits on the size of 
'the operands. The operands are limited by the Long Integer data type,
'which maxes out at 2147483647:

MsgBox (2147483647 + 1) Mod 5	'<--Fails: Runtime error 6: overflow


'In contrast, the 'MOD()' worksheet function returns a Double
'floating point value... always. Also the 'MOD()' worksheet function
'handles negative and decimal operands correctly:

MsgBox [MOD(-11,3)]	   		'<--displays: 1      (Correct)
MsgBox [MOD(11,-3)]	   		'<--displays: -1     (Correct)
MsgBox [MOD(11.5,3)]		'<--displays: 2.5    (Correct)
MsgBox [MOD(2147483648,5)]	'<--displays: 3  	 (Correct)
MsgBox [MOD(11,0.4)]		'<--displays: 0.199999999999999

'But notice the floating point rounding error on the last example 
'above. It should calculate a result of precisely: 0.2

'And, calling the Excel object model is always inefficient, so it
'is better to stay with pure VBA when possible.

'So here is a superior pure VBA function:

Function Mod2(n, divisor)
    Mod2 = CDec(n) - divisor * Int(n / divisor)
End Function

'This VBA function has all of the advantages of the worksheet function
'but is more precise and MUCH faster when called from VBA:
'1) It can correctly return a decimal value
'2) It correctly handles negative arguments
'3) It uses the Decimal Variant data subtype to reduce 
'     floating point error
'4) Because of the Decimal subtype it can handle parameters MUCH
'     larger than even the worksheet function can
'5) It does not call the Excel object model (faster). This also
'     allows it to be used in other VBA environments like Word and Access

MsgBox Mod2(11, 0.4)   	'<--displays: 0.2  (Correct, no rounding error)
MsgBox Mod2(11.5, 3)   	'<--displays: 2.5  (Correct)
MsgBox Mod2(-11, 3)  	'<--displays: 1    (Correct)
MsgBox Mod2(11, -3)  	'<--displays: -1   (Correct)
MsgBox Mod2("9851201567410588", 1349)  	'<--displays: 948   (Correct)
'
'Notice in the final example we pass the first argument as a string.
'This is done to preserve value accuracy as the number is too large
'for even a Double to represent accurately. Notice that the worksheet
'function fails here, whereas the 'Mod2()' function works just fine:

MsgBox [MOD(9851201567410588,1349)]	 '<--Fails: Runtime error 13: type mismatch

'
'
'

Are there any code examples left?
Made with love
This website uses cookies to make IQCode work for you. By using this site, you agree to our cookie policy

Welcome Back!

Sign up to unlock all of IQCode features:
  • Test your skills and track progress
  • Engage in comprehensive interactive courses
  • Commit to daily skill-enhancing challenges
  • Solve practical, real-world issues
  • Share your insights and learnings
Create an account
Sign in
Recover lost password
Or log in with

Create a Free Account

Sign up to unlock all of IQCode features:
  • Test your skills and track progress
  • Engage in comprehensive interactive courses
  • Commit to daily skill-enhancing challenges
  • Solve practical, real-world issues
  • Share your insights and learnings
Create an account
Sign up
Or sign up with
By signing up, you agree to the Terms and Conditions and Privacy Policy. You also agree to receive product-related marketing emails from IQCode, which you can unsubscribe from at any time.
Creating a new code example
Code snippet title
Source