Reputation: 300
I have this function that is working fine when the inputs are number: it returns T
if both inputs have the same sign, NIL
otherwise. However, when I give for example two 'a
, I get this error:
a is not a real number
I'm finding it tricky to filer non numbers without using COND
, IF
, WHEN
, UNLESS
, or CASE
. Here is the function definition I have so far.
(defun same-sign (x y)
(or (and (>= x 0) (>= y 0))
(and (< x 0) (< y 0))))
Upvotes: 1
Views: 114
Reputation: 300
(defun same-sign (x y)
(and (typep x 'real) (typep y 'real)
(or (and (>= x 0) (>= y 0))
(and (< x 0) (< y 0)))))
Upvotes: 0
Reputation: 51501
You can use check-type
:
(defun same-sign (x y)
(check-type real x)
(check-type real y)
(= (signum x) (signum y)))
Since signum can also work with complex numbers, you could use number
instead of real
here, if it makes sense for your application.
Signum
treats 0
separately, though, so you might use minusp
instead (wrapping to potentially un-generalize the boolean):
(defun binary-sign (n)
"Returns -1 if n is negative, 1 otherwise."
(check-type real n)
(if (minusp n) -1 1))
(defun same-sign-p (x y)
"Returns whether both given real numbers are either both negative or both
non-negative."
(= (binary-sign x) (binary-sign y)))
As you see, you can avoid writing two checks by putting the check into the more detailed function. However, you can imagine that minusp
already has such a check, so you can be reasonably sure that an appropriate type-error will be signalled anyway if you don't call this with reals.
Upvotes: 4
Reputation: 816
You might mean type real
and not number
. Type number
consists of real
(integers and floats) and complex
(2 real components) values. An example of a complex number is #C(1 2) = 1 + 2i
Try (and (realp x) ...)
to filter real
numbers, equivalent to (and (typep x 'real) ...)
.
Also (typecase x (real ..))
or using a generic function and (defmethod foo ((x real)) ..)
work, except you seem to want to restrict yourself to basic logical operators.
Upvotes: 1