Mich hat vor einiger Zeit interessiert, wie eigentlich die beiden Lispfunktionen min und max mathematisch ohne Vergleichsoperatoren beschrieben werden.
Na gut, braucht man nicht wirklich, trotzdem fand ich es interessant.
Hier also die Formel für den Mindest- und den Maximalwert von zwei reelen Zahlen.
Die Schreibweise |a-b| steht für den absoluten Betrag, also durch weglassen des Vorzeichens.
Mit diesem Wissen können wir nun unsere eigene Vergleichsfunktion für den Mindest- und Maximalwert zwischen zwei Zahlen programmieren. Damit die Rückgabe identisch mit der jeweiligen Lispfunktion ist, entwickelte ich hierzu insg. 4 Module.
1. Modul -> Intp
Diese Funktion soll bestimmen ob die übergebene Zahl ein ganze Zahl ist (... -3, -2, -1, 0, 1, 2, 3, ...)
; Argument: #num = Zahl
; Rückgabe True wenn es eine ganze Zahl ist
; sonst nil
(defun Intp (#num) (= 'int (type #num)))
2. Modul -> MinMax
Da die Berechnung für den Mindest- und Maximalwert sich nur durch ein arithmetischen Operator unterscheidet, entschied ich mich nur eine Funktion zu schreiben und den Operator einfach als Symbol zu übergeben.
; Argumente
; sym = für min '- oder max '+
; a und b = Zahl
(defun MinMax (sym a b)
(apply sym
(mapcar '(lambda (x) (* x 0.5))
(list (+ a b) (abs (- a b)))
)
)
)
3. und 4. Modul -> MyMin und Mymax
; Argumente
; a und b = Zahl
(defun MyMin (a b)
(if (vl-every 'Intp (list a b))
(fix (MinMax '- a b))
(MinMax '- a b)
)
)
; Argumente
; a und b = Zahl
(defun MyMax (a b)
(if (vl-every 'Intp (list a b))
(fix (MinMax '+ a b))
(MinMax '- a b)
)
)
Da die Funktion MinMax immer eine reele Zahl zurückgibt, prüfe ich bei den Funktionen MyMin und MyMax ob die beide übergebenen Zahlen ganze Zahlen sind. Wen dem so, wird die Rückgabe von MinMax als ganze Zahl ausgegeben (fix).
Prüfen wir unsere neue Funktionen...
(MyMin 3 4) => 3
(MyMin 0.13 4.8) => 0.13
(MyMin 53 4.8) => 4.8
(MyMin -5 -2) => -5
(MyMin -2 0) => -2
(MyMin 2 0) => 0
(MyMin 0 1.34) => 0.0
(MyMax 3 4) => 4
(MyMax 0.13 4.8) => 4.8
(MyMax 53 4.8) => 53.0
(MyMax -5 -2) => -2
(MyMax -2 0) => 0
(MyMax 2 0) => 2
(MyMax 0 1.34) => 1.34
Mit freundlicher Genehmigung von Rolf Wischnewski. Originalbeitrag im Februar 2006, CADmaro.de