Discussion of Common Lisp
-
hill0093
- Posts: 8
- Joined: Sun Sep 21, 2014 12:56 am
Post
by hill0093 » Sun Sep 21, 2014 1:11 am
I'm new to Lisp, using lispworks 6.1 personal on windows seven.
This is a function which will eventually have calDa as its argument.
All the variables should do like 31 bit integer arithmetic like truncated divide.
Lispworks says calDa unbound.
Code: Select all
(defun linDaOfCalDa ()
(declare ((signed-byte 32) linDaOfCalDa calDa yr mo da i r mo14by12 calDaOfLinDa linDa) )
(set calDa 20140920)
(set mo (/ calDa 100))
(set yr (/ calDa 10000))
(set da (- calDa (* mo 100)))
(mo (- mo (* yr 100)))
(mo14by12 (/ (- mo 14) 12))
(i (+ yr 4900 mo14by12))
(r (+ (* (1461 (/ i 4))) 32075) da)
(r (+ r (* 367 (- mo (- 2 (* mo14by12 12))))))
(r (- r (/ (* 3 (/ (+ yr 4900 mo14by12) 100)) 4)))
(linDa (- r 1721060))
return(linDa)
)
Last edited by
nuntius on Sun Sep 21, 2014 2:15 pm, edited 1 time in total.
Reason: added [code][/code] tags
-
Goheeca
- Posts: 271
- Joined: Thu May 10, 2012 12:54 pm
-
Contact:
Post
by Goheeca » Sun Sep 21, 2014 2:38 pm
Because
set evaluates its first argument and it's an unbound symbol
calDa.
Look at this:
Code: Select all
(defvar a nil)
(defvar b (find-symbol "A"))
(set b t)
a ; => t
so you are looking for
devfar &
setq (or
setf) or
let, just check them all out.
-
hill0093
- Posts: 8
- Joined: Sun Sep 21, 2014 12:56 am
Post
by hill0093 » Sun Sep 21, 2014 5:14 pm
Thank you for teaching me. I modified the function.
Why is my answer now an unfinished divide?
And I am still wondering about how to ensure integer arithmetic.
CL-USER 1 > (defun linDaOfCalDa() ;calDa to be future function parameter
(declare ((signed-byte 32) linDaOfCalDa calDa yr mo da i r mo14by12 calDaOfLinDa linDa) )
(setf calDa 20140921) ;this line to be omitted later
(setf mo (/ calDa 100))
(setf yr (/ calDa 10000))
(setf da (- calDa (* mo 100)))
(setf mo (- mo (* yr 100)))
(setf mo14by12 (/ (- mo 14) 12))
(setf i (+ yr 4900 mo14by12))
(setf r (+ (/ (* 1461 i) 4) -32075 da))
(setf r (+ r (* 367 (- mo (- 2 (* mo14by12 12))))))
(setf r (- r (/ (* 3 (/ (+ yr 4900 mo14by12) 100)) 4)))
(setf linDa (- r 1721060))
(setf linDaOfCalDa linDa)
)
LINDAOFCALDA
CL-USER 2 > (linDaOfCalDa)
3063548670337/4000000
CL-USER 3 >
-
Goheeca
- Posts: 271
- Joined: Thu May 10, 2012 12:54 pm
-
Contact:
Post
by Goheeca » Sun Sep 21, 2014 5:38 pm
For the integer division you should look into the
rounding family of functions, you'll probably pick the
floor function +
mod & rem.
The
declare is only for optimization, not for changing the meaning of a program.
-
edgar-rft
- Posts: 226
- Joined: Fri Aug 06, 2010 6:34 am
- Location: Germany
Post
by edgar-rft » Sun Sep 21, 2014 6:41 pm
The "unfinished divide" is a number of type
RATIO:
Code: Select all
(/ 1 2) => 1/2 ; ratio
(/ 1.0 2.0) => 0.5 ; float
(truncate 1 2) => 0 ; integer
More examples can be found in
Practical Common Lisp, Chapter 10, Section
Numbers plus the following few sections, demonstrating Common Lisp math using various types of numbers.
-
hill0093
- Posts: 8
- Joined: Sun Sep 21, 2014 12:56 am
Post
by hill0093 » Sun Sep 21, 2014 8:24 pm
Thank you both for the education.
I will study more tomorrow, bedtime now.
-
hill0093
- Posts: 8
- Joined: Sun Sep 21, 2014 12:56 am
Post
by hill0093 » Tue Sep 23, 2014 12:21 am
I hope yhat I got one small step ahead,
but it says that INTDIV is unbound.
(defun intDiv(num den)
(setf ans (truncate num den))
(print ans)
(return ans)
)
(print intDiv(-3 2))
-
Goheeca
- Posts: 271
- Joined: Thu May 10, 2012 12:54 pm
-
Contact:
Post
by Goheeca » Tue Sep 23, 2014 12:36 am
You have to use the calling convention:
-
hill0093
- Posts: 8
- Joined: Sun Sep 21, 2014 12:56 am
Post
by hill0093 » Tue Sep 23, 2014 4:53 am
I modified the call. Here is Lispworks answer.
Correct answer comes from within function, not return from function?
CL-USER 1 > (defun intDiv(num den)
(setf ans (truncate num den))
(print ans)
(return ans)
)
INTDIV
CL-USER 2 > (print (intDiv -3 2))
-1
Error: Not inside a block named NIL.
-
Goheeca
- Posts: 271
- Joined: Thu May 10, 2012 12:54 pm
-
Contact:
Post
by Goheeca » Tue Sep 23, 2014 5:13 am
You shouldn't use
return in CL. The
defun has an implicit
progn as a body and its value is a value of the last expression so you just write:
Code: Select all
(defun intDiv (num den)
(truncate num den))
or
Code: Select all
(defun intDiv (num den)
(let ((ans (truncate num den)))
ans))