#!/usr/bin/env python3 import numpy as np import timeit import sys sys.setrecursionlimit(10**6) def fact_rec(n): # y = fact_rec(n) berechnet die Fakultät von n als # fact_rec(n) = n * fact_rec(n - 1) mit fact_rec(0) = 1 # Fehler, falls n <0 oder nicht ganzzahlig if n < 0 or np.trunc(n) != n: raise Exception('The factorial is defined only for positive integers') if n <= 1: return 1 else: return n*fact_rec(n-1) def fact_for(n): # y = fact_rec(n) berechnet die Fakultät von n als # fact_rec(n) = n * fact_rec(n - 1) mit fact_rec(0) = 1 # Fehler, falls n <0 oder nicht ganzzahlig if n < 0 or np.trunc(n) != n: raise Exception('The factorial is defined only for positive integers') if n <= 1: return 1 else: fak = 1 for num in range(n): fak *= n n -= 1 return fak if __name__ == "__main__": t1 = timeit.repeat( "fact_rec(500)", "from __main__ import fact_rec", number=100) t2 = timeit.repeat( "fact_for(500)", "from __main__ import fact_for", number=100) print("fact_for ist um den Faktor: %s schneller als fact_rec" % str( np.average(t1) / np.average(t2))) # FRAGE: Welche der beiden Funktionen ist schneller und um was für einen Faktor? # fact_for ist um den Faktor 8 schneller als fact_rec bei n = 500 # FRAGE: Weshalb? # Rekursion an sich braucht mehr ressourcen in Python(Java, C), # weil man einen Stack benötigt. # Das heisst, dass neben den Berechnungen, gibt es noch # Stack operationen bei der Rekursion, was wiederum erklärt warum # es einbisschen langsamer ist # FRAGE: Gibt es in Python eine obere Grenze für die Fakultät von n # FRAGE: als ganze Zahl (integer)? # Aus stackoverflow: # "In Python 3, this question doesn't apply. The plain int type is unbounded." # Das bedeutet eine Grenze gibt es nicht, aber je nach Zahl kann es # viel länger brauchen # FRAGE: als reelle Zahl (float)? # Ja, es gibt eine Grenze die liegt bei sys.float_info.max