Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ;;
- ;; Preamble: Lisp prerequisits
- ;;
- ;; These two lines sets the number of binary digits used to represent a float
- ;; in Lisp. This is necessary because you'll be working with tiny numbers
- ;; TL;DR ignore these two lines
- (setf (EXT:LONG-FLOAT-DIGITS) 35000)
- (setf *read-default-float-format* 'long-float)
- ;; This method rounds a number to a certain precision
- ;; It takes two arguments: the number to round and the number of digits to
- ;; round in decimals
- ;;
- ;; Example: (roundToPrecision 10.0044 3) -> 10.004
- (defun roundToPrecision (number precision)
- (let
- ((p (expt 10 precision)))
- (/ (round (* number p)) p)
- )
- )
- ;;
- ;; Exercise
- ;;
- ;; Exercise
- ;; Your task is to implement the Gauss-Legendre algorithm for calculating pi
- ;; and extract 10.000 (ten thousand) digits
- (write-line "Pi opgave")
- (setf an 1)
- (setf bn 0.709219858) ; 1/√2 = 1/1.41 = 0.709219858
- (setf tn 0.25) ; 1/4 = 0.25
- (setf pn 1)
- (defun nextA (an bn)
- "Documentation for nextA."
- (/ (+ an bn) 2)
- )
- (defun nextT (an pn tn bn)
- "Documentation for nextT."
- (- tn (* pn (expt (- an (nextA an bn)) 2)))
- )
- (defun nextB (an bn)
- "Documentation for nextB."
- (sqrt (* an bn))
- )
- (defun nextP (pn)
- "Documentation for nextP."
- (* 2 pn)
- )
- (defun calcPi (an bn tn pn piOld)
- "Documentation for calcPi."
- (let (
- (aNew (nextA an bn))
- (bNew (nextB an bn))
- (tNew (nextT an pn tn bn))
- (pNew (nextP pn))
- )
- (let
- ((piNew (roundToPrecision (/ (expt (+ aNew bNew) 2) (* 4 tNew)) 15)
- )
- )
- (if
- (= (roundToPrecision piNew 100) (roundToPrecision piOld 100))
- piNew
- (calcPi aNew bNew tNew pNew piNew)
- )
- )
- ))
- (write (coerce (calcPi 1L0 (/ 1L0 (sqrt 2L0)) (/ 1L0 4L0) 1L0 1L0) 'long-float))
- ;; Gauss-Legendre algorithm on Wikipedia
- ;; https://en.wikipedia.org/wiki/Gauss%E2%80%93Legendre_algorithm
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement