Name: Anonymous 2009-10-08 17:16
if you guys really think you are geniuses then write a java program that can approximate the sin function for any angle between 0 and 360 using taylor expansions
(defun factorial (x)
(reduce #'* (loop for i from 1 upto x collect i)))
(defun help (x)
(let (result
(n 0))
(lambda ()
(setq result
(* (/ (expt -1 n)
(factorial (1+ (* 2 n))))
(expt x (1+ (* 2 n)))))
(incf n)
result)))
(defun doit (x approximation)
(do* ((i 0 (1+ i))
(f (help x))
(y (funcall f)
(if (oddp i)
(- y (funcall f))
(+ y (funcall f)))))
((= i approximation) y)))
(define (fact x)
(if (zero? x)
1
(* x (fact (- x 1)))))
(define (taylor-series x max-power)
(define (iter total power sign)
(if (> power max-power)
total
(iter (sign total (/ (expt x power)
(fact power)))
(+ power 2)
(if (eq? sign +)
-
+))))
(iter 0 1 +))
(define (deg->rad x)
(* (/ x 180) pi))
(define (mysin x)
(taylor-series (deg->rad x) 9)) ;<- 9 is a magic number
;;; This definition needs proper optimization directives on
;;; some implementations for it to do TCO, otherwise I would just have used a LOOP
(defun factorial (x)
(labels ((rec (x acc)
(if (< x 2)
acc
(rec (1- x) (* x acc)))))
(rec x 1)))
(defun slow-sin (x &optional (precision 0.001))
"Calculates sin x with a given precision. Returns a ratio. "
(let ((current-value x)
(step 1)
(sign nil))
(labels ((next-sin ()
(incf current-value
(* (if sign 1 -1)
(/ (expt x step) (factorial step))))
(incf step 2)
current-value))
(let ((result (next-sin)))
(loop until (< (- result (next-sin)) precision)
do (setf result current-value))
result))))
(defun inexact-sin (x &optional (precision 0.00001))
"Calculates sin x with a given precision. Returns a floating point value."
(coerce (slow-sin x precision) 'float))
(filter (lambda (x) (< (abs (- (sin x) (mysin x))) 0.00001))
(unfold (lambda (x) (> x 360))
(lambda (x) x)
(lambda (x) (+ x 1))
1))
()TaylorSeriesFactoryFactoryManagerBuilder or some such nonsense