Mathematik mit VBA - Teil 1: Primzahlen, Bruchrechnen, Kombinatronik und Statistik

    • VBA: Sonstige

    Es gibt 5 Antworten in diesem Thema. Der letzte Beitrag () ist von roddy.

      Mathematik mit VBA - Teil 1: Primzahlen, Bruchrechnen, Kombinatronik und Statistik

      Zur Zeit arbeite ich an einem privaten Projekt: Ich überlege mir für viele mathematische Zusammenhänge, wie sie mit VBA lösbar sind. Ich mache das einfach, weil es mir Spaß macht. Und teilweise nützt es mir auch bei meinen „nützlichen“ Projekten.

      Die Fälle, bei denen es in VBA schon Funktionen gibt (z. B. Sin, Cos, Abs), werde ich natürlich nicht behandeln. Sie sind in der VB-Hilfe unter dem Stichwort „Mathematische Funktionen“ zu finden.

      Hier sind die Sachen, die ich bisher gemacht habe:

      Primzahlen und Primfaktorzerlegung

      Eine Primzahl ist eine Zahl, die nicht mehr und nicht weniger als zwei Teiler hat: 1 und die Zahl selbst. Da es unendlich viele Primzahlen gibt, benutze ich ein Array, in das während der Laufzeit so viele Werte wie nötig hinzugefügt werden.

      Um möglichst große Zahlen verarbeiten zu können, habe ich „Double“ gewählt. Da Primzahlen jedoch nur ganze, positive Zahlen sein können, lasse ich für Parameter nur solche Werte zu bzw. runde Werte. Und dass „Double“ nur 15 signifikante Stellen zulässt, führt dazu, dass ab 10^15 keine korrekten Werte herauskommen, somit lasse ich auch für diese Fälle eine Fehlermeldung erscheinen.

      Visual Basic-Quellcode

      1. Enum PrimArrayTyp
      2. nachNr = 0
      3. nachPrimzahl = 1
      4. End Enum
      5. Dim PrimArray() As Double
      6. 'Array von Primzahlen
      7. Dim PrimIndex() As Double
      8. 'Array von Index-Nummern von Primzahlen (umgekehrte Zuordnung wie "PrimArray")
      9. 'Diese beiden Arrays werden zur Laufzeit soweit aufgefüllt wie nötig.



      Visual Basic-Quellcode

      1. Function teilbar(a As Double, b As Double) As Boolean
      2. 'Gibt zurück, ob a durch b teilbar ist.
      3. If a < 0 Or b < 0 Or CStr(a) <> CStr(Int(a)) Or CStr(b) <> CStr(Int(b)) Or a >= 10 ^ 15 Or b >= 10 ^ 15 Then MsgBox "Ungültiger Parameterwert!", vbCritical: Stop
      4. teilbar = (Round(a - Int(a / b) * b, 0) = 0)
      5. End Function
      6. Sub PrimInit()
      7. 'Dient zur Festlegung von Anfangswerten, wenn "PrimArray" und "PrimIndex" noch nicht dimensioniert sind.
      8. Dim x As Double
      9. On Error GoTo Leer
      10. x = UBound(PrimArray)
      11. Exit Sub
      12. Leer:
      13. ReDim PrimIndex(1 To 2)
      14. PrimIndex(1) = 0
      15. PrimIndex(2) = 1
      16. ReDim PrimArray(1 To 1)
      17. PrimArray(1) = 2
      18. End Sub
      19. Function Primzahl(Zahl As Double) As Boolean
      20. 'Gibt zurück, ob "Zahl" eine Primzahl ist.
      21. Dim i As Double
      22. If Zahl < 0 Or CStr(Zahl) <> CStr(Int(Zahl)) Or Zahl >= 10 ^ 15 Then MsgBox "Ungültiger Parameterwert!", vbCritical: Stop
      23. PrimInit
      24. Primzahl = True
      25. If Zahl <= 1 Then
      26. Primzahl = False
      27. ElseIf UBound(PrimIndex) < Zahl Then
      28. For i = 1 To PrimzahlNr(Int(Sqr(Zahl)))
      29. If teilbar(Zahl, Primzahlen(i)) Then
      30. Primzahl = False
      31. Exit For
      32. End If
      33. Next
      34. Else
      35. Primzahl = (PrimArray(PrimIndex(Zahl)) = Zahl)
      36. End If
      37. End Function
      38. Sub PrimzahlPrüf()
      39. 'Prüft, ob die erste noch nicht geprüfte Zahl eine Primzahl ist
      40. 'und füllt "PrimArray" und "PrimIndex" entsprechend auf.
      41. If Primzahl(UBound(PrimIndex) + 1) Then
      42. ReDim Preserve PrimArray(1 To UBound(PrimArray) + 1)
      43. PrimArray(UBound(PrimArray)) = UBound(PrimIndex) + 1
      44. End If
      45. ReDim Preserve PrimIndex(1 To UBound(PrimIndex) + 1)
      46. PrimIndex(UBound(PrimIndex)) = UBound(PrimArray)
      47. End Sub
      48. Function Primzahlen(Index As Double) As Double
      49. 'Liefert die Primzahl an der Stelle "Index". Primzahlen(100) liefert die 100. Primzahl.
      50. Dim p As Boolean
      51. If Index < 1 Or CStr(Index) <> CStr(Int(Index)) Or Index >= 10 ^ 15 Then MsgBox "Ungültiger Parameterwert!", vbCritical: Stop
      52. PrimInit
      53. While UBound(PrimArray) < Index
      54. PrimzahlPrüf
      55. Wend
      56. Primzahlen = PrimArray(Index)
      57. End Function
      58. Function PrimzahlNr(Zahl As Double) As Double
      59. 'Liefert die Primzahl-Index-Nr. der größten Primzahl, die kleiner oder gleich "Zahl" ist.
      60. Dim p As Boolean
      61. If Zahl < 1 Or CStr(Zahl) <> CStr(Int(Zahl)) Or Zahl >= 10 ^ 15 Then MsgBox "Ungültiger Parameterwert!", vbCritical: Stop
      62. PrimInit
      63. While UBound(PrimIndex) < Zahl
      64. PrimzahlPrüf
      65. Wend
      66. PrimzahlNr = PrimIndex(Zahl)
      67. End Function
      68. Function PrimzahlArray(Typ As PrimArrayTyp, von As Double, bis As Double) As Variant
      69. 'Liefert ein Array, das die Primzahlen zwischen "von" und "bis" enthält.
      70. 'Wenn "nachNr" ausgewählt wird, liefert es mit von=1 und bis=100 die ersten 100 Primzahlen.
      71. 'Wenn "nachPrimzahl" ausgewählt wird, liefert es mit von=1 und bis=100 die Primzahlen bis 100.
      72. Dim p() As Double
      73. Dim v As Double, i As Double
      74. If Typ = nachPrimzahl Then
      75. v = PrimzahlNr(von)
      76. If v = 0 Then v = 1
      77. If Primzahlen (v) < von Then v = v + 1
      78. von = v
      79. bis = PrimzahlNr(bis)
      80. End If
      81. If bis < von Then
      82. PrimzahlArray = Split("", " ")
      83. Else
      84. ReDim p(bis - von)
      85. For i = von To bis
      86. p(i - von) = Primzahlen(i)
      87. Next
      88. PrimzahlArray = p
      89. End If
      90. End Function
      91. Function PrimzahlAnzahl(von As Double, bis As Double) As Double
      92. 'Liefert die Anzahl der Primzahlen zwischen "von" und "bis".
      93. PrimzahlAnzahl = UBound(PrimzahlArray(nachPrimzahl, von, bis)) + 1
      94. End Function

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „roddy“ ()

      Visual Basic-Quellcode

      1. Function Primfaktoren(Zahl As Double) As Variant
      2. 'Liefert die Primfaktoren von "Zahl" als eindimensionales Array.
      3. 'Primfaktoren(60) liefert {2,2,3,5}, denn 2*2*3*5=60.
      4. Dim pf() As Double
      5. Dim i As Double, Faktor As Double
      6. If Zahl <= 1 Or CStr(Zahl) <> CStr(Int(Zahl)) Or Zahl >= 10 ^ 15 Then MsgBox "Ungültiger Parameterwert!", vbCritical: Stop
      7. ReDim pf(0)
      8. i = 0
      9. While Zahl > 1
      10. i = i + 1
      11. Faktor = Primzahlen(i)
      12. Do While teilbar(Zahl, Faktor) Or Faktor > Sqr(Zahl)
      13. If Faktor > Sqr(Zahl) Then Faktor = Zahl
      14. If pf(0) = Empty Then
      15. pf(0) = Faktor
      16. Else
      17. ReDim Preserve pf(UBound(pf) + 1)
      18. pf(UBound(pf)) = Faktor
      19. End If
      20. Zahl = Round(Zahl / Faktor, 0)
      21. If Zahl = 1 Then Exit Do
      22. Loop
      23. Wend
      24. Primfaktoren = pf
      25. End Function
      26. Function Primfaktoren2(Zahl As Double) As Variant
      27. 'Liefert die Primfaktoren von "Zahl" als zweidimensionales Array (Faktor, Exponent).
      28. 'Primfaktoren2(60) liefert {(2,2),(3,1),(5,1)}, denn (2^2)*(3^1)*(5^1)=60.
      29. Dim pf() As Double, p() As Double
      30. Dim i As Double, Faktor As Double
      31. If Zahl <= 1 Or CStr(Zahl) <> CStr(Int(Zahl)) Or Zahl >= 10 ^ 15 Then MsgBox "Ungültiger Parameterwert!", vbCritical: Stop
      32. ReDim pf(1)
      33. i = 0
      34. While Zahl > 1
      35. i = i + 1
      36. Faktor = Primzahlen(i)
      37. Do While teilbar(Zahl, Faktor) Or Faktor > Sqr(Zahl)
      38. If Faktor > Sqr(Zahl) Then Faktor = Zahl
      39. If pf(0) = Empty Then
      40. pf(0) = Faktor
      41. pf(1) = 1
      42. Else
      43. If pf(UBound(pf) - 1) = Faktor Then
      44. pf(UBound(pf)) = pf(UBound(pf)) + 1
      45. Else
      46. ReDim Preserve pf(UBound(pf) + 2)
      47. pf(UBound(pf) - 1) = Faktor
      48. pf(UBound(pf)) = 1
      49. End If
      50. End If
      51. Zahl = Round(Zahl / Faktor, 0)
      52. If Zahl = 1 Then Exit Do
      53. Loop
      54. Wend
      55. ReDim p((UBound(pf) + 1) / 2 - 1, 1)
      56. For i = 0 To UBound(pf) Step 2
      57. p(i / 2, 0) = pf(i)
      58. p(i / 2, 1) = pf(i + 1)
      59. Next
      60. Primfaktoren2 = p
      61. End Function
      62. Function Teiler(Zahl As Double) As Variant
      63. 'Liefert alle Teiler von "Zahl" als Array.
      64. Dim pf() As Double, d() As Double, t() As Double, n As Double, z() As Double
      65. Dim i As Double, Wert As Double, j As Double, k As Double, x As Double
      66. pf = Primfaktoren2(Zahl)
      67. ReDim d(UBound(pf, 1))
      68. n = 1
      69. For i = 0 To UBound(pf, 1)
      70. d(i) = n
      71. n = n * (pf(i, 1) + 1)
      72. Next
      73. If n - 1 >= 10 ^ 15 Then MsgBox "Ungültiger Parameterwert!", vbCritical: Stop
      74. ReDim t(n - 1)
      75. For i = 0 To n - 1
      76. ReDim z(UBound(d))
      77. Wert = i
      78. For j = UBound(d) To 0 Step -1
      79. For k = pf(j, 1) To 1 Step -1
      80. If Wert >= d(j) * k Then
      81. z(j) = k
      82. Wert = Wert - d(j) * k
      83. End If
      84. Next
      85. Next
      86. t(i) = 1
      87. For j = 0 To UBound(z)
      88. t(i) = t(i) * pf(j, 0) ^ z(j)
      89. Next
      90. Next
      91. 'Die folgende Schleife dient der Sortierung.
      92. For i = 0 To n - 1
      93. For j = 0 To i - 1
      94. If t(i) < t(j) Then
      95. x = t(i)
      96. For k = i To j + 1 Step -1
      97. t(k) = t(k - 1)
      98. Next
      99. t(j) = x
      100. End If
      101. Next
      102. Next
      103. Teiler = t
      104. End Function

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „roddy“ ()

      Größter gemeinsamer Teiler, kleinstes gemeinsames Vielfaches und Bruchrechnen

      Für Brüche benutze ich einen benutzerdefinierten Datentyp mit Zähler und Nenner. Der andere (Dezimal) ist für rationale Dezimalzahlen. Anstatt, dass man nur 15 signifikante Stellen hat, kann man hiermit und der Funktion „BruchInDezimal“ alle Stellen vor dem Komma, alle einmal auftretenden Stellen nach dem Komma sowie die periodischen, unendlichen Stellen erfassen, also somit die komplette Zahl in Dezimalform. Daneben habe ich auch die üblichen Bruch-Operationen dargestellt sowie ggT und kgV.

      Visual Basic-Quellcode

      1. Type Brüche
      2. Zähler As Double
      3. Nenner As Double
      4. End Type
      5. Type Dezimal
      6. vorKomma As String
      7. 'Stellt die Ziffern vor dem Komma dar.
      8. nachKomma As String
      9. 'Stellt die Ziffern nach dem Komma vor der Periode dar.
      10. Periode As String
      11. 'Stellt die Ziffern dar, die sich unendlich oft wiederholen.
      12. End Type



      Visual Basic-Quellcode

      1. Function Divisionsrest(a As Double, b As Double) As Double
      2. 'Liefert den Divisionsrest von "a / b". Entspricht "a Mod b", jedoch auf "Double"-Ebene.
      3. If CStr(a) <> CStr(Int(a)) Or CStr(b) <> CStr(Int(b)) Or a >= 10 ^ 15 Or b >= 10 ^ 15 Then MsgBox "Ungültiger Parameterwert!", vbCritical: Stop
      4. Divisionsrest = Round(a - Int(a / b) * b, 0)
      5. End Function
      6. Function ggT(ParamArray Zahl() As Variant) As Double
      7. 'Liefert den größten gemeinsamen Teiler der "Zahl"-Werte.
      8. Dim i As Integer, ungültig As Boolean
      9. Dim a As Double, b As Double, Rest As Double
      10. ungültig = (UBound(Zahl) = -1)
      11. For i = 0 To UBound(Zahl)
      12. ungültig = (ungültig Or Zahl(i) <= 0 Or CStr(Zahl(i)) <> CStr(Int(Zahl(i))) Or Zahl(i) >= 10 ^ 15)
      13. Next
      14. If ungültig Then MsgBox "Ungültiger Parameterwert!", vbCritical: Stop
      15. Select Case UBound(Zahl)
      16. Case 0: ggT = Zahl(0)
      17. Case 1
      18. If Zahl(0) > Zahl(1) Then
      19. a = Zahl(0): b = Zahl(1)
      20. Else
      21. a = Zahl(1): b = Zahl(0)
      22. End If
      23. Do
      24. Rest = Divisionsrest(a, b)
      25. If Rest = 0 Then Exit Do
      26. a = b
      27. b = Rest
      28. Loop
      29. ggT = b
      30. Case Else
      31. ggT = Zahl(0)
      32. For i = 1 To UBound(Zahl)
      33. ggT = ggT(ggT, Zahl(i))
      34. Next
      35. End Select
      36. End Function
      37. Function kgV(ParamArray Zahl() As Variant) As Double
      38. 'Liefert das kleinste gemeinsame Vielfache der "Zahl"-Werte.
      39. Dim i As Integer, ungültig As Boolean
      40. Dim Nenner As Double
      41. ungültig = (UBound(Zahl) = -1)
      42. For i = 0 To UBound(Zahl)
      43. ungültig = (ungültig Or Zahl(i) <= 0 Or CStr(Zahl(i)) <> CStr(Int(Zahl(i))) Or Zahl(i) >= 10 ^ 15)
      44. Next
      45. If ungültig Then MsgBox "Ungültiger Parameterwert!", vbCritical: Stop
      46. Select Case UBound(Zahl)
      47. Case 0: kgV = Zahl(0)
      48. Case 1
      49. kgV = Round(Zahl(0) / ggt(Zahl(0), Zahl(1)) * Zahl(1), 0)
      50. Case Else
      51. kgV = Zahl(0)
      52. For i = 1 To UBound(Zahl)
      53. kgV = kgV(kgV, Zahl(i))
      54. Next
      55. End Select
      56. End Function
      57. Function Bruchwert(Bruch As Brüche) As Double
      58. 'Liefert den Wert von "Bruch".
      59. Bruchwert = Bruch.Zähler / Bruch.Nenner
      60. End Function
      61. Function Erweitern(Bruch As Brüche, Faktor As Double) As Brüche
      62. 'Erweitert "Bruch" mit "Faktor".
      63. Erweitern.Zähler = Bruch.Zähler * Faktor
      64. Erweitern.Nenner = Bruch.Nenner * Faktor
      65. End Function
      66. Function Kürzen(Bruch As Brüche, Faktor As Double) As Brüche
      67. 'Kürzt "Bruch" durch "Faktor"
      68. Kürzen.Zähler = Bruch.Zähler / Faktor
      69. Kürzen.Nenner = Bruch.Nenner / Faktor
      70. End Function
      71. Function negBruch(Bruch As Brüche) As Brüche
      72. 'Kehrt das Vorzeichen von "Bruch" um.
      73. negBruch.Zähler = -Bruch.Zähler
      74. negBruch.Nenner = Bruch.Nenner
      75. End Function
      76. Function Kehrwert(Bruch As Brüche) As Brüche
      77. 'Bildet den Kehrwert von "Bruch".
      78. Kehrwert.Zähler = Bruch.Nenner
      79. Kehrwert.Nenner = Bruch.Zähler
      80. End Function
      81. Function BruchPotenz(Bruch As Brüche, Exponent As Double) As Brüche
      82. 'Potenziert "Bruch" mit "Exponent".
      83. BruchPotenz.Zähler = Bruch.Zähler ^ Exponent
      84. BruchPotenz.Nenner = Bruch.Nenner ^ Exponent
      85. End Function
      86. Function Normalbruch(Bruch As Brüche) As Brüche
      87. 'Kürzt "Bruch" so, dass Zähler und Nenner teilerfremd und ganzzahlig sind.
      88. Dim a As Double, b As Double
      89. Dim aE() As String, bE() As String, aKomma() As String, bKomma() As String
      90. Dim aStellen As Integer, bStellen As Integer, Stellen As Integer
      91. a = Bruch.Zähler
      92. b = Bruch.Nenner
      93. aE = Split(a, "E")
      94. bE = Split(b, "E")
      95. aKomma = Split(aE(0), ",")
      96. bKomma = Split(bE(0), ",")
      97. aStellen = 0
      98. bStellen = 0
      99. If UBound(aKomma) = 1 Then aStellen = Len(aKomma(1))
      100. If UBound(bKomma) = 1 Then bStellen = Len(bKomma(1))
      101. If UBound(aE) = 1 Then aStellen = aStellen - aE(1)
      102. If UBound(bE) = 1 Then bStellen = bStellen - bE(1)
      103. If bStellen > aStellen Then Stellen = bStellen Else Stellen = aStellen
      104. Bruch = Erweitern(Bruch, 10 ^ Stellen)
      105. Normalbruch = Kürzen(Bruch, Sgn(Bruch.Nenner) * ggT(Abs(Bruch.Zähler), Abs(Bruch.Nenner)))
      106. End Function

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „roddy“ ()

      Visual Basic-Quellcode

      1. Function BruchAdd(Bruch1 As Brüche, Bruch2 As Brüche) As Brüche
      2. 'Addiert "Bruch1" und "Bruch2".
      3. Dim Hauptnenner As Double
      4. Dim i As Integer
      5. Bruch1 = Normalbruch(Bruch1)
      6. Bruch2 = Normalbruch(Bruch2)
      7. Hauptnenner = kgV(Bruch1.Nenner, Bruch2.Nenner)
      8. Bruch1 = Erweitern(Bruch1, Hauptnenner / Bruch1.Nenner)
      9. Bruch2 = Erweitern(Bruch2, Hauptnenner / Bruch2.Nenner)
      10. BruchAdd.Zähler = Bruch1.Zähler + Bruch2.Zähler
      11. BruchAdd.Nenner = Hauptnenner
      12. BruchAdd = Normalbruch(BruchAdd)
      13. End Function
      14. Function BruchSubtr(Bruch1 As Brüche, Bruch2 As Brüche) As Brüche
      15. 'Subtrahiert "Bruch2" von "Bruch1".
      16. BruchSubtr = BruchAdd(Bruch1, negBruch(Bruch2))
      17. End Function
      18. Function BruchMult(Bruch1 As Brüche, Bruch2 As Brüche) As Brüche
      19. 'Multipliziert "Bruch1" mit "Bruch2".
      20. BruchMult.Zähler = Bruch1.Zähler * Bruch2.Zähler
      21. BruchMult.Nenner = Bruch1.Nenner * Bruch2.Nenner
      22. BruchMult = Normalbruch(BruchMult)
      23. End Function
      24. Function BruchDiv(Bruch1 As Brüche, Bruch2 As Brüche) As Brüche
      25. 'Dividiert "Bruch1" durch "Bruch2".
      26. BruchDiv = BruchMult(Bruch1, Kehrwert(Bruch2))
      27. End Function
      28. Function BruchInDezimal(Bruch As Brüche) As Dezimal
      29. 'Wandelt "Bruch" in eine Dezimalzahl um.
      30. Dim a As String, b As Double
      31. Dim i As Integer, r() As Double, k As Double, Rest As Double
      32. Bruch = Normalbruch(Bruch)
      33. a = Format(Abs(Bruch.Zähler), "0")
      34. b = Bruch.Nenner
      35. ReDim r(b)
      36. With BruchInDezimal
      37. Rest = 0
      38. For i = 1 To Len(a)
      39. .vorKomma = .vorKomma & Int((Rest * 10 + Mid(a, i, 1)) / b)
      40. Rest = Divisionsrest((Rest * 10 + Mid(a, i, 1)), b)
      41. Next
      42. .vorKomma = Format(Sgn(Bruch.Zähler) * .vorKomma, "0")
      43. While Rest > 0
      44. k = k + 1
      45. r(k) = Rest
      46. .nachKomma = .nachKomma & Int((Rest * 10) / b)
      47. Rest = Divisionsrest((Rest * 10), b)
      48. For i = 1 To k
      49. If Rest = r(i) Then
      50. .Periode = Mid(.nachKomma, i, b)
      51. .nachKomma = Left(.nachKomma, i - 1)
      52. Rest = 0
      53. Exit For
      54. End If
      55. Next
      56. Wend
      57. End With
      58. End Function
      59. Function DezimalInBruch(Zahl As Dezimal) As Brüche
      60. 'Wandelt "Zahl" in einen Bruch um.
      61. Dim a As String, b As String, c As String
      62. a = Zahl.vorKomma
      63. b = Zahl.nachKomma
      64. c = Zahl.Periode
      65. With DezimalInBruch
      66. If Len(c) = 0 Then
      67. .Zähler = a & b
      68. .Nenner = 10 ^ Len(b)
      69. Else
      70. .Zähler = (a & b & c) - (a & b)
      71. .Nenner = (10 ^ Len(c) - 1) * 10 ^ Len(b)
      72. End If
      73. End With
      74. DezimalInBruch = Normalbruch(DezimalInBruch)
      75. End Function

      Kombinatronik

      Die Anzahl der Permuationen ist die Anzahl der möglichen Anordnungen für eine bestimmte Anzahl (n) von Objekten, von denen jeweils k1, k2, k3 ... Objekte gleich sind (Für die Zeichenfolge AABCDD ist n=6, k1=2, k2=1, k3=1, k4=2). Man kann sie mit dem Polynomialkoeffizienten berechnen. Sind alle Objekte verschieden, ist somit k1=k2=k3=...=1, ist dies gleichbedeutend mit der Fakultät von n (n!).

      Bei den Kombinationen spielt die Anordnung keine Rolle. Aus einer Gesamtzahl von Objekten (n) werden k Elemente ausgewählt. Die Anzahl lässt sich durch den Binomialkoeffizienten bestimmen. Ohne Wiederholung bedeutet dabei, dass ein Element nur einmal ausgewählt werden kann (wie z. B. bei einem Lotto-Tipp, dort ist n=49 und k=6). Mit Wiederholung bedeutet, dass man Elemente auch mehrmals auswählen kann, jedoch insgesamt nur k Stück (z. B. wenn man bei einer Wahl einem Kandidaten auch mehrere Stimmen geben kann, jedoch insgesamt nur eine bestimmte Anzahl Stimmen hat).

      Variationen sind ähnlich wie Kombinationen, nur dass es auf die Anordnung ankommt. Die Anzahl ohne Wiederholung lässt sich durch unten stehende Funktion „VariOhne“ berechnen, mit Wiederholung durch n^k. Variationen ohne Wiederholung mit n=k entspricht den Permutationen, bei denen alle Objekte unterschiedlich sind (auch rechnerisch ergibt sich in diesem Fall n!).

      Da nur ganze positive Zahlen herauskommen können, runde ich und lasse als Parameter auch nur ganze Zahlen zu.

      Visual Basic-Quellcode

      1. Function Fakultät(n As Double) As Double
      2. 'Liefert die Fakultät von "n" (n!).
      3. 'Entspricht der Anzahl der Permutationen, wenn sich alle Objekte unterscheiden.
      4. Dim i As Double
      5. If n < 0 Or CStr(n) <> CStr(Int(n)) Or n >= 10 ^ 15 Then MsgBox "Ungültiger Parameterwert!", vbCritical: Stop
      6. Fakultät = 1
      7. For i = 1 To n
      8. Fakultät = Fakultät * i
      9. Next
      10. Fakultät = Round(Fakultät, 0)
      11. End Function
      12. Function BinKoeff(n As Double, k As Double) As Double
      13. 'Liefert den Binomialkoeffizienten von "n" und "k" (n über k).
      14. 'Entspricht den Kombinationen ohne Wiederholung.
      15. 'Die Anzahl der Kombinationen mit Wiederholung ist BinKoeff(n+k-1,k).
      16. Dim i As Double
      17. If k < 0 Or CStr(k) <> CStr(Int(k)) Or k >= 10 ^ 15 Or n >= 10 ^ 15 Then MsgBox "Ungültiger Parameterwert!", vbCritical: Stop
      18. BinKoeff = 1
      19. For i = 1 To k
      20. BinKoeff = BinKoeff * (n - i + 1) / i
      21. Next
      22. BinKoeff = Round(BinKoeff, 0)
      23. End Function
      24. Function PolynKoeff(n As Double, ParamArray k() As Variant) As Double
      25. 'Liefert den Polynomialkoeffizienten von "n" und den "k"-Werten.
      26. 'Entspricht den Permutationen. Die "k"-Werte stellen die Anzahlen der jeweiligen Objekte dar.
      27. Dim r As Double, i As Double, s As Double
      28. Dim Divisor() As Double, j As Double, l As Double
      29. ungültig = (n < 0 Or CStr(n) <> CStr(Int(n)) Or n >= 10 ^ 15)
      30. If n < 0 Then MsgBox "n muss größer oder gleich 0 sein!": Stop
      31. r = UBound(k) + 1
      32. For i = 0 To r - 1
      33. ungültig = (ungültig Or k(i) < 0 Or CStr(k(i)) <> CStr(Int(k(i))) Or k(i) >= 10 ^ 15)
      34. s = s + k(i)
      35. Next
      36. If ungültig Or s <> n Then MsgBox "Ungültiger Parameterwert!", vbCritical: Stop
      37. ReDim Divisor(n)
      38. l = 0
      39. For i = 0 To r - 1
      40. For j = 1 To k(i)
      41. l = l + 1
      42. Divisor(l) = j
      43. Next
      44. Next
      45. PolynKoeff = 1
      46. For i = 1 To n
      47. PolynKoeff = PolynKoeff * i / Divisor(i)
      48. Next
      49. PolynKoeff = Round(PolynKoeff, 0)
      50. End Function
      51. Function VariOhne(n As Double, k As Double) As Double
      52. 'Liefert die Variationen ohne Wiederholung.
      53. 'Die Anzahl der Variationen mit Wiederholung ist n^k.
      54. Dim i As Double
      55. VariOhne = 1
      56. For i = n - k + 1 To n
      57. VariOhne = VariOhne * i
      58. Next
      59. VariOhne = Round(VariOhne, 0)
      60. End Function

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „roddy“ ()

      Hier noch ein paar statistische Größen. Das arithmetische Mittel ist der Mittelwert, den man am häufigsten verwendet (Summe/Anzahl). Daneben gibt es noch das geometrische Mittel (n-te Wurzel des Produkts der Werte; n=Anzahl) und das harmonische Mittel (Anzahl * Kehrwert der Summe der Kehrwerte der Werte).

      Visual Basic-Quellcode

      1. Function Minimum(ParamArray x() As Variant) As Double
      2. 'Liefert das Minimum der "x"-Werte.
      3. Dim i As Integer
      4. Minimum = x(0)
      5. For i = 1 To UBound(x)
      6. If x(i) < Minimum Then Minimum = x(i)
      7. Next
      8. End Function
      9. Function Maximum(ParamArray x() As Variant) As Double
      10. 'Liefert das Maximum der "x"-Werte.
      11. Dim i As Integer
      12. Maximum = x(0)
      13. For i = 1 To UBound(x)
      14. If x(i) > Maximum Then Maximum = x(i)
      15. Next
      16. End Function
      17. Function arithMittel(ParamArray x() As Variant) As Double
      18. 'Liefert das arithmetische Mittel der "x"-Werte.
      19. Dim n As Integer, i As Integer
      20. n = UBound(x) + 1
      21. arithMittel = 0
      22. For i = 0 To n - 1
      23. arithMittel = arithMittel + x(i) / n
      24. Next
      25. End Function
      26. Function geoMittel(ParamArray x() As Variant) As Double
      27. 'Liefert das geometrische Mittel der "x"-Werte.
      28. Dim n As Integer, i As Integer
      29. n = UBound(x) + 1
      30. geoMittel = 1
      31. For i = 0 To n - 1
      32. geoMittel = geoMittel * x(i) ^ (1 / n)
      33. Next
      34. End Function
      35. Function harmMittel(ParamArray x() As Variant) As Double
      36. 'Liefert das harmonische Mittel der "x"-Werte.
      37. Dim n As Integer, i As Integer
      38. n = UBound(x) + 1
      39. harmMittel = 0
      40. For i = 0 To n - 1
      41. harmMittel = harmMittel + 1 / x(i)
      42. Next
      43. harmMittel = n / harmMittel
      44. End Function


      Anregungen, Meinungen, Kritik u. ä. sind willkommen. Da ich nur VBA kenne, weiß ich nicht, was man anpassen/verändern muss, um es in anderen VB-Sprachen benutzen zu können.

      Momentan arbeite ich am Rechnen mit komplexen Zahlen und Nullstellen von ganzrationalen Funktionen. Dies wird dann zu Teil 2 gehören. Wann dies soweit ist, kann ich noch nicht sagen, da ich nur sporadisch Zeit dafür finde.

      Soviel hierzu einstweilen.

      MfG

      roddy