1. Вычисление квадратного корня
Я специально определил собственный вариант функции abs, мне так интереснее :)
;;;; Приближённое вычисление квадратного корня
;; Модуль числа
(defun abs-value (num)
(if (> num 0.0)
num
(- 0.0 num)))
;; Логическая функция, возвращающая истину,
;; если числа a и b отличаются друг от друга
;; менее, чем на precision
(defun precision-ok (a b precision)
(< (abs-value (- a b)) precision))
;; Рекурсивная функция, использующая root
;; как приближённое значение корня num.
;; Функция вызывает сама себя до тех пор,
;; пока точность результата не достигнет precision
(defun square-root-iter (num root precision)
(if (precision-ok num (* root root) precision)
root
(square-root-iter num (/ (+ (/ num root) root) 2) precision)))
;; "Лицо" функции вычисления квадратного корня
;; Использует 1.0 в качестве приближённого значения корня
;; и точность 0.001
(defun square-root (num)
(square-root-iter num 1.0 0.001))
;; Вычисление квадратного корня 25
(square-root 25.0)
2. Вычисление числа из ряда Фибоначчи
Для примера я решил вычислить двдацатитысячное по порядку число в ряду Фибоначчи.
;;;; Вычисление 20000-го числа в ряду Фибоначчи
;; Рекурсивная функция, вычисляющая число Фибоначчи
;; Вызывает себя num раз, используя a и b в качестве
;; двух предыдущих чисел в ряду
(defun fib-iter (a b num)
(if (eql num 1)
a
(fib-iter b (+ a b) (- num 1))))
;; "Лицо" функции вычисления числа Фибоначчи
(defun fib (num)
(fib-iter 1 1 num))
;; Вычисление 20000-го числа в ряду Фибоначчи
(fib 20000)
3. Вычисление числа Фи ("Золотого сечения") двумя способами
Сначала я воспользовался для вычислений уже полученной в прошлом примере функцией для вычисления чисел Фибоначчи, а затем написал второй вариант функции, более оптимизированный.
;;;; Сравнение двух способов вычисления числа Фи
;;;; - "Золотого сечения"
;; Рекурсивная функция, вычисляющая число Фибоначчи
;; Вызывает себя num раз, используя a и b в качестве
;; двух предыдущих чисел в ряду
(defun fib-iter (a b num)
(if (eql num 1)
a
(fib-iter b (+ a b) (- num 1))))
;; "Лицо" функции вычисления числа Фибоначчи
(defun fib (num)
(fib-iter 1 1 num))
;; Вычисление числа Фи через два вызова функции,
;; вычисляющей число в ряду Фибоначчи
(defun phi ()
(* 1.0 (/ (fib 2000) (fib 1999))))
;; Вычисление числа Фи
;; Совмещённое вычисление двух последовательных
;; чисел в ряду Фибоначчи с последующим делением
;; следующего числа на предыдущее
(defun phi2-iter (a b num)
(if (eql num 1)
(* 1.0 (/ b a))
(phi2-iter b (+ a b) (- num 1))))
;; "Лицо" функции вычисления числа Фи
(defun phi2 ()
(phi2-iter 1 1 2000))
;; Сравниваем результаты вычисления обеих функций,
;; попутно измеряя время, потраченное на вычисления
;; Первая функция должна быть медленнее в 2 раза
;; второй
(eql (time (phi)) (time (phi2)))
А вот и результаты работы программы:
Evaluation took:
0.001 seconds of real time
0.000000 seconds of total run time (0.000000 user, 0.000000 system)
0.00% CPU
2,279,699 processor cycles
400,944 bytes consed
Evaluation took:
0.001 seconds of real time
0.000000 seconds of total run time (0.000000 user, 0.000000 system)
0.00% CPU
1,470,207 processor cycles
204,584 bytes consed
T
Первая функция не только отработала медленнее, но и затребовала для своего выполнения почти в два раза больше памяти.
Комментариев нет:
Отправить комментарий