Results 1 to 8 of 8

Thread: Handy Maths Snippets

  1. #1

    Thread Starter
    Retired VBF Adm1nistrator plenderj's Avatar
    Join Date
    Jan 2001
    Location
    Dublin, Ireland
    Posts
    10,359

    Handy Maths Snippets

    Here are some maths functions/routines implemented in VB.
    They may be of use to some of you.

    If you have any comments or suggestions, or have any pieces of code you'd like me to add, just let me know.

    Contents, in order;
    00) Constant Pi
    01) Constant e
    02) isDivisor()
    03) recursiveGCD()
    04) iterativeGCD()
    05) eulerPhi()
    06) nextPrimeDivisor()
    07) isPrime()
    08) factors()
    09) powerMod()
    10) binaryToDecimal()
    11) decimalToBinary()
    12) factorial()
    13) binomial()
    14) toCharacterCode()
    15) linesCrossed()
    16) NAND
    17) NOR
    18) XNOR

    VB Code:
    1. Option Explicit
    2.  
    3. [b]'' Mathematical Constants
    4. ''[/b]
    5. Const Pi                As Single = 3.14159265358979
    6. Const e                 As Single = 2.71828182845905
    7.  
    8.  
    9.  
    10. [b]'' Number Theory Related
    11. ''
    12. '' IsDivisor, RecursiveGCD, IterativeGCD,
    13. '' EulerPhi, NextPrimeDivisor, IsPrime
    14. ''[/b]
    15. Public Function isDivisor(ByVal nDenominator As Long, ByVal nNumerator As Long) As Boolean
    16.     isDivisor = ((nNumerator Mod nDenominator) = 0)
    17. End Function
    18.  
    19. Public Function recursiveGCD(ByVal num1 As Long, ByVal num2 As Long) As Long
    20.     If (num1 = 1) Or (num2 = 1) Then
    21.         recursiveGCD = 1
    22.     Else
    23.         If (num1 = num2) Then
    24.             recursiveGCD = num1
    25.         Else
    26.             If (num1 > num2) Then
    27.                 recursiveGCD = recursiveGCD(num1 - num2, num2)
    28.             Else
    29.                 recursiveGCD = recursiveGCD(num2 - num1, num1)
    30.             End If
    31.         End If
    32.     End If
    33. End Function
    34.  
    35. Public Function iterativeGCD(ByVal num1 As Long, ByVal num2 As Long) As Long
    36.     If (num1 <> 0) And (num2 <> 0) Then
    37.         If num1 = 1 Or num2 = 1 Then iterativeGCD = 1
    38.         Dim i As Long, j As Long, n As Long, largestGCD As Long
    39.         Dim divisors1() As Long, divisors2() As Long
    40.         ReDim divisors1(0), divisors2(0)
    41.         For i = 1 To num1
    42.             If IsDivisor(i, num1) Then
    43.                 divisors1(UBound(divisors1)) = i
    44.                 ReDim Preserve divisors1(UBound(divisors1) + 1)
    45.             End If
    46.         Next
    47.         For i = 1 To num2
    48.             If IsDivisor(i, num2) Then
    49.                 divisors2(UBound(divisors2)) = i
    50.                 ReDim Preserve divisors2(UBound(divisors2) + 1)
    51.             End If
    52.         Next
    53.         n = IIf(UBound(divisors1) > UBound(divisors2), num2, num1)
    54.         For i = 0 To UBound(divisors1)
    55.             For j = 0 To UBound(divisors2)
    56.                 If (divisors1(i) = divisors2(j)) Then If divisors1(i) > largestGCD Then largestGCD = divisors1(i)
    57.             Next
    58.         Next
    59.         iterativeGCD = largestGCD
    60.     Else
    61.         iterativeGCD = -1
    62.     End If
    63. End Function
    64.  
    65. Public Function eulerPhi(ByVal nX As Long) As Long
    66.     Dim i As Long
    67.     For i = 1 To nX
    68.         If (GCD(i, nX) = 1) Then
    69.             eulerPhi = eulerPhi + 1
    70.         End If
    71.     Next i
    72. End Function
    73.  
    74. Public Function nextPrimeDivisor(ByVal divisorGiven As Long, ByVal nX As Long) As Long
    75.     nextPrimeDivisor = 0
    76.     If (divisorGiven < nX) Then
    77.         Dim i As Long
    78.         For i = (divisorGiven + 1) To nX
    79.             If (IsDivisor(i, nX) And IsPrime(i) And (i <> nX)) Then
    80.                 nextPrimeDivisor = i
    81.         Exit Function
    82.             End If
    83.         Next i
    84.     End If
    85. End Function
    86.  
    87. Public Function isPrime(ByVal nX As Long) As Boolean
    88.     If (nX = 1) Then isPrime = False
    89.     If (nX = 2) Then isPrime = True
    90.     isPrime = True
    91.    
    92.     Dim i As Long
    93.     For i = 2 To nX - 1
    94.         If Not (GCD(nX, i) = 1) Then
    95.             isPrime = False
    96.             Exit For
    97.         End If
    98.     Next i
    99. End Function
    100.  
    101. Public Function factors(ByVal nX As Long, ByVal onlyReturnPrimeFactors As Boolean) As Long()
    102.     Dim retVal() As Long
    103.     ReDim retVal(0)
    104.     If (Not IsPrime(nX)) Then
    105.         Dim i As Long
    106.         For i = 1 To nX
    107.             If (IsDivisor(i, nX)) Then
    108.                 If ((onlyReturnPrimeFactors And IsPrime(i)) Or Not onlyReturnPrimeFactors) Then
    109.                     retVal(UBound(retVal)) = i
    110.                     ReDim Preserve retVal(UBound(retVal) + 1)
    111.                 End If
    112.             End If
    113.         Next i
    114.     End If
    115.     factors = retVal
    116. End Function
    117.  
    118. Public Function powerMod(ByVal a As Long, ByVal b As Long, ByVal n As Long) As Long
    119.     powerMod = (a ^ b) Mod n
    120. End Function
    121.  
    122.  
    123.  
    124. [b]'' Miscellaneous
    125. ''
    126. '' BinaryToDecimal, DecimalToBinary, Factorial, Binomial, ToCharacterCode
    127. ''[/b]
    128. Public Function binaryToDecimal(ByVal binaryString As String) As Long
    129.     If (Not Len(binaryString) > 1023) Then
    130.         If (binaryString <> "") And (Replace(Replace(binaryString, "1", ""), "0", "") = "") Then
    131.             Dim i As Long
    132.             binaryString = StrReverse(binaryString)
    133.             For i = 0 To Len(binaryString)
    134.                 If (Mid(binaryString, i + 1, 1) = 1) Then
    135.                     binaryToDecimal = binaryToDecimal + (2 ^ (i))
    136.                 End If
    137.             Next i
    138.         End If
    139.         binaryToDecimal = retVal
    140.     Else
    141.         MsgBox "Overflow would occur"
    142.         Exit Function
    143.     End If
    144. End Function
    145.  
    146. Public Function decimalToBinary(ByVal nDecimal As Long) As String
    147.         Dim nTemp As Long
    148.         nTemp = nDecimal
    149.         Do
    150.             decimalToBinary = IIf(((nTemp / 2) = CLng(nTemp / 2)), "0", "1") & decimalToBinary
    151.             nTemp = (nTemp - 0.1) / 2
    152.             If (nTemp < 1) Then Exit Do
    153.         Loop
    154. End Function
    155.  
    156. Public Function factorial(ByVal nX As Double) As Double
    157.     If (nX = 1) Then
    158.         factorial = 1
    159.     Else
    160.         factorial = nX * factorial(nX - 1)
    161.     End If
    162. End Function
    163.  
    164. Public Function binomial(ByVal n As Long, ByVal m As Long) As Double
    165.     Dim tempTopLine As Long
    166.     Dim tempBottomLine As Long
    167.     tempTopLine = 1
    168.     tempBottomLine = 1
    169.     Dim i As Long
    170.     If (n > m) Then
    171.         For i = n To ((n - m) + 1) Step -1
    172.             tempTopLine = tempTopLine * i
    173.         Next i
    174.         For i = 1 To m
    175.             tempBottomLine = tempBottomLine * i
    176.         Next i
    177.     End If
    178.     Binomial = tempTopLine / tempBottomLine
    179. End Function
    180.  
    181. Public Function toCharacterCode(ByVal strString As String, Optional ByVal strDelimeter As String) As String
    182.     Dim i As Long
    183.     Dim nStrLen As Long
    184.     nStrLen = Len(strString)
    185.     toCharacterCode = Asc(Left(strString, 1))
    186.     If (nStrLen >= 1) Then
    187.         For i = 2 To nStrLen
    188.             toCharacterCode = Asc(Mid(strString, i, 1)) & strDelimeter & toCharacterCode
    189.         Next i
    190.     End If
    191.     ToCharacterCode = retVal
    192. End Function
    193.  
    194. Public Function linesCrossed(ByRef line1 As Line, ByRef line2 As Line) As Boolean
    195.     linesCrossed = False
    196.     Dim dx1 As Double, dy1 As Double, dx2 As Double, dy2 As Double
    197.     Dim n As Double, s As Double
    198.     dx1 = line1.X2 - line1.X1
    199.     dy1 = line1.Y2 - line1.Y1
    200.     dx2 = line2.X2 - line2.X1
    201.     dy2 = line2.Y2 - line2.Y1
    202.     n = 0#: s = 0#
    203.     If ((dx2 * dy1) - (dy2 * dx1) <> 0) Then
    204.         n = (dx1 * (line2.Y1 - line1.Y1) + dy1 * (line1.X1 - line2.X1)) / (dx2 * dy1 - dy2 * dx1)
    205.         s = (dx2 * (line1.Y1 - line2.Y1) + dy2 * (line2.X1 - line1.X1)) / (dy2 * dx1 - dx2 * dy1)
    206.         linesCrossed = ((s >= 0) And (s <= 1) And (n >= 0) And (n <= 1))
    207.     End If
    208. End Function
    209.  
    210.  
    211.  
    212. [b]'' Boolean Operations
    213. ''
    214. '' NAND, NOR, XNOR
    215. ''[/b]
    216. Public Function NAND(ByVal bit1 As Boolean, ByVal bit2 As Boolean) As Boolean
    217.     NAND = Not (bit1 And bit2)
    218. End Function
    219.  
    220. Public Function NOR(ByVal bit1 As Boolean, ByVal bit2 As Boolean) As Boolean
    221.     NOR = Not (bit1 Or bit2)
    222. End Function
    223.  
    224. Public Function XNOR(ByVal bit1 As Boolean, ByVal bit2 As Boolean) As Boolean
    225.     XNOR = Not (bit1 Xor bit2)
    226. End Function
    Last edited by plenderj; May 23rd, 2002 at 03:18 AM.
    Microsoft MVP : Visual Developer - Visual Basic [2004-2005]

  2. #2

    Thread Starter
    Retired VBF Adm1nistrator plenderj's Avatar
    Join Date
    Jan 2001
    Location
    Dublin, Ireland
    Posts
    10,359
    * 21-October-2004 - Moved to CodeBank *
    Microsoft MVP : Visual Developer - Visual Basic [2004-2005]

  3. #3
    PowerPoster Fox's Avatar
    Join Date
    Jan 2000
    Location
    *afk*
    Posts
    2,088

    Playing with 2 points...

    The following functions are part of my Tile Engine Tutorial; thought they'd fit here.
    Both accept 2 input points given by X and Y coordinates.

    1) GetDistance
    VB Code:
    1. Public Function GetDistance(X1 As Long, Y1 As Long, X2 As Long, Y2 As Long) As Long
    2.    
    3.     '// Returns the distance between the given points
    4.     '// by [email][email protected][/email] - [url]http://vbfx.yhoko.com/[/url]
    5.    
    6.     GetDistance = Sqr(CDbl(X2 - X1) ^ 2 + CDbl(Y2 - Y1) ^ 2)
    7. End Function

    2) GetAngle
    VB Code:
    1. Public Function GetAngle(X1 As Single, Y1 As Single, X2 As Single, Y2 As Single) As Single
    2.    
    3.     '// Returns the angle between the given points
    4.     '// by [email][email protected][/email] - [url]http://vbfx.yhoko.com/[/url]
    5.    
    6.     Dim TempX As Single
    7.     Dim TempY As Single
    8.     Dim Angle As Single
    9.    
    10.     Const Pi As Single = 3.141593
    11.     Const Pi2 As Single = 6.283185
    12.    
    13.     'Get difference
    14.     TempX = (X2 - X1)
    15.     TempY = (Y2 - Y1)
    16.    
    17.     'Special case X
    18.     If TempX = 0 Then
    19.         If Y2 > Y1 Then
    20.             Angle = Pi * 0.5
    21.         ElseIf Y2 < Y1 Then
    22.             Angle = Pi * 1.5
    23.         End If
    24.    
    25.         'Return angle
    26.         GetAngle = Angle
    27.         Exit Function
    28.     End If
    29.    
    30.     'Special case Y
    31.     If TempY = 0 Then
    32.         If X2 > X1 Then
    33.             Angle = 0
    34.         ElseIf X2 < X1 Then
    35.             Angle = Pi
    36.         End If
    37.    
    38.         'Return angle
    39.         GetAngle = Angle
    40.         Exit Function
    41.     End If
    42.    
    43.     'Get angle
    44.     Angle = Atn(Abs(TempY) / Abs(TempX))
    45.    
    46.     'Calculate angle
    47.     If TempX < 0 And TempY > 0 Then: Angle = Pi - Angle
    48.     If TempX < 0 And TempY < 0 Then: Angle = Pi + Angle
    49.     If TempX > 0 And TempY < 0 Then: Angle = Pi2 - Angle
    50.    
    51.     'Put in range
    52.     If Angle < 0 Then: Angle = Angle + Pi2
    53.    
    54.     'Return angle
    55.     GetAngle = Angle
    56. End Function
    Last edited by Fox; Sep 12th, 2008 at 10:46 PM. Reason: Links updated

  4. #4

    Thread Starter
    Retired VBF Adm1nistrator plenderj's Avatar
    Join Date
    Jan 2001
    Location
    Dublin, Ireland
    Posts
    10,359

    Re: Handy Maths Snippets

    bump
    Microsoft MVP : Visual Developer - Visual Basic [2004-2005]

  5. #5
    Addicted Member
    Join Date
    Feb 2006
    Location
    The Sea of Tranquility
    Posts
    252

    Re: Handy Maths Snippets

    VB Code:
    1. Private Sub Form_Load()
    2.  
    3. MsgBox getAngleBetweenLines(4, 2, 9, 1, 0, 0)
    4.  
    5. End Sub
    6.  
    7. Private Function getAngleBetweenLines(commonX As Single, commonY As Single, X1 As Single, Y1 As Single, Y2 As Single, X2 As Single) As Double
    8.  
    9. Const Pi As Single = 3.141593
    10. Dim length As Double, differnceX1 As Double, differenceX2 As Double, differenceY1 As Double, differenceY2 As Double, other As Double
    11.  
    12. differenceX1 = commonX - X1
    13. differenceY1 = commonY - Y1
    14. differenceX2 = commonX - X2
    15. differenceY2 = commonY - Y2
    16.  
    17. getAngleBetweenLines = invCos(((differenceX1 * differenceX2) + (differenceY1 * differenceY2)) / _
    18. (Sqr(CDbl(differenceX1) ^ 2 + CDbl(differenceY1) ^ 2) * Sqr(CDbl(differenceX2) ^ 2 + CDbl(differenceY2) ^ 2)))
    19.  
    20.  
    21.  
    22. End Function
    23.  
    24. Private Function invCos(x As Double) As Double
    25. If x = 1 Then
    26. invCos = Pi
    27. Else
    28.  
    29. invCos = (Atn(-x / Sqr(-x * x + 1)) + 2 * Atn(1))
    30. End If
    31.  
    32. End Function
    Rich

    A)bort, R)etry, I)nfluence with large hammer.
    Please take a moment to rate useful posts.

  6. #6
    Junior Member
    Join Date
    Mar 2005
    Posts
    26

    Re: Handy Maths Snippets

    Mostly nice stuff. I haven't had time to take anything more than a very brief look. One comment:

    The For loop in isPrime only needs to run from 2 to nX/2-1 and not all the way to nX-1.

  7. #7
    Junior Member
    Join Date
    Mar 2005
    Posts
    26

    Re: Handy Maths Snippets

    Again, this is just for speed and consistency.

    In the getAngleBetweenLines code:
    One can save one Sqr in the denominator of the main calculation because Sqr(a)*Sqr(b) = Sqr(a*b)
    Also, in the invCos function, 2*Atn(1) is a constant (pi/2). One should calculate or define that as a constant before hand (or simply use the definition of pi already provided) to save an additional Atn calcuation each time the routine is called.

  8. #8
    Junior Member
    Join Date
    Mar 2005
    Posts
    26

    Re: Handy Maths Snippets

    I should also add: isn't it generally faster to calculate x*x than x^2?

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width