Mathematik mit Standard-Modulen¶
In jeder Python-Installation ist das Standard-Modul math enthalten. Es enthält zahlreiche Funktionen, die aus dem Python-Interpreter einen umfangreichen und programmierbaren Taschenrechner machen.
Das math
-Modul wird meistens in folgender Form eingebunden:
import math as m
Anschließend kann so das math
-Modul unter der Bezeichnung m
angesprochen
werden; dies spart Tipp-Arbeit. Als einzige (verkraftbare) Einschränkung hat
dies zur Folge, dass keine andere Variable mit m
benannt werden darf.
Das math
-Modul enthält unter anderem folgende Funktionen, die jeweils auf
einzelne Zahlenwerte angewendet werden können:
m.pow(zahl,n) |
![]() ![]() ![]() |
m.sqrt(zahl) |
Quadrat-Wurzel einer positiven Zahl |
m.exp(x) |
Exponentialfunktion ![]() ![]() |
m.log(x, a) |
Logarithmusfunktion
![]() ![]() ![]() |
m.radians(winkelwert) |
Winkelumrechnung von Grad auf Radians |
m.degrees(winkelwert) |
Winkelumrechnung von Radians auf Grad |
m.sin(x) , m.cos(x) und m.tan(x) |
Trigonometrische Funktionen für ![]() |
m.asin(x) , m.acos(x) und m.atan(x) |
Umkehrfunktionen der trigonometrischen Funktionen (Ergebnisse in Radians) |
math.floor(zahl) |
Nächst kleinerer int -Wert ![]() ![]() |
math.ceil(zahl) |
Nächst größerer int -Wert ![]() ![]() |
Zudem sind im math
-Modul die Konstanten m.pi
und m.e
für die
Kreiszahl beziehungsweise die Eulersche Zahl
vordefiniert.
Neben dem math
-Modul existieren weiter für mathematische Zwecke nützliche
Module, beispielsweise cmath für das Rechnen mit komplexen
Zahlen oder functools
für das Anwenden von Operatoren
und/oder Funktionen auf eine ganze Liste von Zahlen. Im folgenden werden einige
Anwendungsbeispiele vorgestellt, die sich an den Aufgaben zur Arithmetik orientieren.
Primfaktor-Zerlegung
Um die Primfaktoren einer ganzen Zahl zu bestimmen, kann man
folgende Funktion nutzen (Quelle: StackOverflow):
def prim(n):
'''Calculates all prime factors of the given integer.'''
from math import sqrt
pfactors = []
limit = int(sqrt(n)) + 1
check = 2
num = n
if n == 1:
return [1]
for check in range(2, limit):
while num % check == 0:
pfactors.append(check)
num /= check
if num > 1:
pfactors.append(num)
return pfactors
Die Grund-Idee von diesem Algorithmus liegt darin, dass eine Zahl keinen
Primzahl-Faktor haben kann, der größer ist als die Quadratwurzel dieser Zahl.
Für ist beispielsweise
der größtmögliche
Faktor, der eine Primzahl sein könnte.
- Andere Produkte mit größeren Faktoren
lassen sich zwar ebenfalls bilden, enthalten dann allerdings stets einen Faktor, der kleiner als die Quadrat-Wurzel der Original-Zahl ist.
- Die einzelnen möglichen Primfaktoren lassen sich finden, indem man
nacheinander die Faktoren
in aufsteigender Reihenfolge durchprobiert. Um eine mögliche Mehrfachheit einzelner Faktoren nicht außer Acht zu lassen, muss bei jedem gefundenen Faktor geprüft werden, ob sich die Original-Zahl gegebenenfalls auch mehrfach durch diesen dividieren lässt.
- Ist ein Faktor gefunden, so kann man die Original-Zahl durch diesen dividieren und den Algorithmus erneut mit dem resultierenden Divisions-Rest fortsetzen.
Die gefundenen Faktoren sind tatsächlich allesamt Primzahlen: Jeder andere Faktor ließe sich selbst als Produkt jeweils kleinerer Primzahlen darstellen. Die Teilbarkeit durch diese Zahlen wurde im Lauf des Algorithmus allerdings bereits geprüft; der jeweilige Divisionsrest, mit dem der Algorithmus fortfährt, enthält diese Faktoren nicht mehr.
Mittels der obigen Funktion kann nun die Primzahl einer Zahl oder eines Zahlenbereichs folgendermaßen berechnet werden:
# Einzelne Zahl in Primfaktoren zerlegen:
prim(2017)
# Zahlenbereich in Primfaktoren zerlegen:
for n in range(1,1000):
print(prim(n))
Größter gemeinsamer Teiler und kleinstes gemeinsames Vielfaches
Beim Rechnen mit rationalen Zahlen, insbesondere beim Kürzen eines Bruchterms oder beim Multiplizieren zweier Brüche, ist es nützlich, den größten gemeinsamen Teiler zweier Zahlen zu finden. Hierzu wird bis heute ein Algorithmus verwendet, den bereits Euklid in der Antike entdeckt hat:
Hat man zwei Zahlen
und
mit
, so ist der größte gemeinsame Teiler von
und
identisch mit dem größten gemeinsamen Teiler von
und
. Man kann also wiederholt immer wieder die kleinere Zahl von der größeren abziehen und das Prinzip erneut anwenden, solange bis man beim größten gemeinsamen Teiler angekommen ist.
Ist beispielsweise
und
, so ist der größte gemeinsame Teiler dieser beider Zahlen identisch mit dem der Zahlen
und
. erneut kann man die Differenz beider Zahlen bilden und erhält damit das Zahlenpaar
und
; ein wiederholtes Anwenden des gleichen Prinzips liefert das zunächst das Zahlenpaar
und
und schließlich
und
; der größte gemeinsame Teiler beider Zahlen ist somit
.
Ist die eine Zahl
wesentlich größer als die andere Zahl
, so müsste bei Anwendung des vorherigen Algorithmus sehr oft
von
subtrahiert werden. Ist beispielsweise
und
, so ergäbe die erste Differenz
, die zweite Differenz
, usw. Bei Verwendung eines Computers ist es effektiver, anstelle der wiederholten Subtraktion eine Modulo-Rechnung vorzunehmen, also bei einer Division mit Rest nur auf den Divisionsrest zu achten. Hier ergibt
den Wert
; der Algorithmus kann somit unmittelbar mit
fortgeführt werden und liefert schon im dritten Schritt als Ergebnis
. Der größte gemeinsame Teiler
wurde so in nur drei Rechenschritten bestimmt.
In Python lässt sich diese zweite, schnellere Variante des Euklidschen
Algorithmus dank des Modulo-Operators %
mit nur sehr wenig Code
implementieren.
def gcd_simple(a, b):
'''Quite simple implementation of Euclid's Algorithm.'''
while b != 0:
tmp = a % b
a = b
b = tmp
return a
Dieser Code lässt sich noch weiter optimieren. Der Trick der folgenden
Implementierung besteht darin, dass der Zuweisungsoperator =
eine geringere
Priorität besitzt als der Modulo-Operator, und somit erst die rechte Seite
ausgewertet wird, bevor die Ergebnisse in die links angegebenen Variablen
gespeichert werden; dies erspart das Speichern der Zwischenergebnisse in
temporären Variablen:
def gcd(a, b):
'''Return the greatest common divisor using Euclid's Algorithm.'''
while b:
a, b = b, a % b
return a
Hat man den größten gemeinsamen Teiler gefunden, so kann auch das kleinste gemeinsame Vielfache zweier Zahlen einfach berechnet werden: Man multipliziert beide Zahlen miteinander und dividiert das Ergebnis anschließend durch den größten gemeinsamen Teiler. In Python könnte die entsprechende Funktion also folgendermaßen aussehen:
def lcm(a, b):
'''Return lowest common multiple.'''
return a * b / gcd(a, b)
Möchte man das kleinste gemeinsame Vielfache nicht nur zweier, sondern einer
Liste mit beliebig vielen ganzen Zahlen ermitteln, so müsste man die obige
lcm()
-Funktion iterativ auf die einzelnen Elemente der Liste anwenden. Nutzt
man hierfür die Funktion reduce()
aus dem Standard-Modul functools, so lässt sich der Algorithmus folgendermaßen implementieren
(Quelle: Stackoverflow):
import functools as ft
def lcmm(*args):
'''turn lcm of args.'''
return ft.reduce(lcm, args)
# Beispiel:
lcmm(6, 13, 27, 84)
# Ergebnis: 9828
… to be continued …