Hi,
I've recently started using XLISP 2.1e for DOS, and found it has
the following math function:
"(signum <expr>) GET THE SIGN OF
A NUMBER Defined in common.lsp
<expr> the number
returns zero if number is zero, one if positive, or negative
one if negative. Numeric type is same as
number. For a complex number, returns unit
magnitude but same phase as number."
it works fine for real numbers, not so for complex numbers:
error: bad argument type - #c([real] [imag])
the code in the included common.lsp file is:
(defun signum (x)
(cond ((not (numberp x)) (error "not a number" x))
((zerop x) x)
(T (/ x (abs x)))))
I wrote some extra code. (signum x) still gives me the same error
msg, but (signum-imag x) works fine on its own (pardon lack of
white space, I can't see it):
; square function required to calculate initial radius
; for complex numbers
(defun sqr (n) (* n n))
; signum, partially altered
(defun signum (x)
(cond ((not (numberp x)) (error "not a number" x))
((zerop x) x)
((= (imagpart x) 0) (/ x (abs x)))
; error msg for below option:
(t (signum-imag x))))
; but it works fine on its own:
; by David R. Sky, December 16, 2005
; released under terms of the Gnu Public License
(defun signum-imag (x)
(setf radius
(sqrt (+ (sqr (realpart x))
(sqr (imagpart x)))))
(complex (/ (realpart x) radius)
(/ (imagpart x) radius)))
Is the problem with my code or with XLISP 2.1e, and how can I fix
the problem?
Thanks
David
"David R. Sky" <···@viper.wapvi.bc.ca> wrote in message
·····································@viper.wapvi.bc.ca...
> Hi,
>
> I've recently started using XLISP 2.1e for DOS, and found it has
> the following math function:
>
> "(signum <expr>) GET THE SIGN OF
> A NUMBER Defined in common.lsp
> <expr> the number
> returns zero if number is zero, one if positive, or negative
> one if negative. Numeric type is same as number. For a
> complex number, returns unit
> magnitude but same phase as number."
>
> it works fine for real numbers, not so for complex numbers:
>
> error: bad argument type - #c([real] [imag])
>
> the code in the included common.lsp file is:
>
> (defun signum (x)
> (cond ((not (numberp x)) (error "not a number" x))
> ((zerop x) x)
> (T (/ x (abs x)))))
>
> I wrote some extra code. (signum x) still gives me the same error
> msg, but (signum-imag x) works fine on its own (pardon lack of
> white space, I can't see it):
Could your problem be that you've given your function a name identical to
Lisp's own name? This can cause an error break if you don't first "shadow"
the installation function. But just giving it a new name will of course
also
fix the problem. If I rename your function it works fine in LispWorks. If
it
still fails for you then I guess XLISP 2.1e for DOS is not your friend.
> ; square function required to calculate initial radius ; for complex
> numbers (defun sqr (n) (* n n))
>
> ; signum, partially altered
> (defun signum (x)
> (cond ((not (numberp x)) (error "not a number" x))
> ((zerop x) x)
> ((= (imagpart x) 0) (/ x (abs x)))
> ; error msg for below option:
> (t (signum-imag x))))
>
> ; but it works fine on its own:
> ; by David R. Sky, December 16, 2005
> ; released under terms of the Gnu Public License
> (defun signum-imag (x)
> (setf radius (sqrt (+ (sqr (realpart x))
> (sqr (imagpart x)))))
> (complex (/ (realpart x) radius)
> (/ (imagpart x) radius)))
As your code is written, using <setf> causes the variable "radius"
to be classified as "special". It should be bound using <let>.
With these modifications everything works fine.
CL-USER 1 >
(defun my-signum (x)
(cond ((not (numberp x)) (error "not a number" x))
((zerop x) x)
((= (imagpart x) 0) (/ x (abs x)))
; error msg for below option:
(t (signum-imag x))))
MY-SIGNUM
CL-USER 2 >
(defun sqr (n) (* n n))
SQR
CL-USER 3 >
(defun signum-imag (x)
(let ((radius
(sqrt (+ (sqr (realpart x))
(sqr (imagpart x))))))
(complex (/ (realpart x) radius)
(/ (imagpart x) radius))))
SIGNUM-IMAG
CL-USER 4 >
(my-signum 123)
1
CL-USER 5 >
(my-signum -123)
-1
CL-USER 6 >
(my-signum 0)
0
CL-USER 7 > (my-signum #c(3 -9))
#C(0.31622776601683794 -0.9486832980505138)
Hi Carl,
Carl: Could your problem be that you've given your function a name
identical to Lisp's own name? This can cause an error break if you
don't first "shadow" the installation function. But just giving it
a new name will of course also fix the problem.
David: I don't understand what you mean, I did name my function
differently from signum, I called it signum-imag.
As I wrote it, signum-imag works whether I input a real or complex
number (it returns a complex number), as does your <let> code. But
I wanted signum-imag to be called from within the common.lsp signum
when it encountered a complex number.
With your code adjustments I still get an error message when I type
for example
(signum #c(0 1))
error: bad argument type #c(0 1)
but
(signum-imag #c(0 1))
returns the correct
#c(0 1)
Thanks
David
On Sun, 18 Dec 2005, Carl Taylor wrote:
>
> "David R. Sky" <···@viper.wapvi.bc.ca> wrote in message
> ·····································@viper.wapvi.bc.ca...
>> Hi,
>>
>> I've recently started using XLISP 2.1e for DOS, and found it has
>> the following math function:
>>
>> "(signum <expr>) GET THE SIGN OF
>> A NUMBER Defined in common.lsp
>> <expr> the number
>> returns zero if number is zero, one if positive, or negative
>> one if negative. Numeric type is same as number. For a
>> complex number, returns unit
>> magnitude but same phase as number."
>>
>> it works fine for real numbers, not so for complex numbers:
>>
>> error: bad argument type - #c([real] [imag])
>>
>> the code in the included common.lsp file is:
>>
>> (defun signum (x)
>> (cond ((not (numberp x)) (error "not a number" x))
>> ((zerop x) x)
>> (T (/ x (abs x)))))
>>
>> I wrote some extra code. (signum x) still gives me the same error
>> msg, but (signum-imag x) works fine on its own (pardon lack of
>> white space, I can't see it):
>
> Could your problem be that you've given your function a name identical to
> Lisp's own name? This can cause an error break if you don't first "shadow"
> the installation function. But just giving it a new name will of course also
> fix the problem. If I rename your function it works fine in LispWorks. If
> it
> still fails for you then I guess XLISP 2.1e for DOS is not your friend.
>
>> ; square function required to calculate initial radius ; for complex
>> numbers (defun sqr (n) (* n n))
>>
>> ; signum, partially altered
>> (defun signum (x)
>> (cond ((not (numberp x)) (error "not a number" x))
>> ((zerop x) x)
>> ((= (imagpart x) 0) (/ x (abs x)))
>> ; error msg for below option:
>> (t (signum-imag x))))
>>
>> ; but it works fine on its own:
>> ; by David R. Sky, December 16, 2005
>> ; released under terms of the Gnu Public License
>> (defun signum-imag (x)
>> (setf radius (sqrt (+ (sqr (realpart x))
>> (sqr (imagpart x)))))
>> (complex (/ (realpart x) radius)
>> (/ (imagpart x) radius)))
>
> As your code is written, using <setf> causes the variable "radius"
> to be classified as "special". It should be bound using <let>.
>
> With these modifications everything works fine.
>
> CL-USER 1 >
> (defun my-signum (x)
> (cond ((not (numberp x)) (error "not a number" x))
> ((zerop x) x)
> ((= (imagpart x) 0) (/ x (abs x)))
> ; error msg for below option:
> (t (signum-imag x))))
> MY-SIGNUM
>
> CL-USER 2 >
> (defun sqr (n) (* n n))
> SQR
>
> CL-USER 3 >
> (defun signum-imag (x)
> (let ((radius
> (sqrt (+ (sqr (realpart x))
> (sqr (imagpart x))))))
> (complex (/ (realpart x) radius)
> (/ (imagpart x) radius))))
> SIGNUM-IMAG
>
> CL-USER 4 >
> (my-signum 123)
> 1
>
> CL-USER 5 >
> (my-signum -123)
> -1
>
> CL-USER 6 >
> (my-signum 0)
> 0
>
> CL-USER 7 > (my-signum #c(3 -9))
> #C(0.31622776601683794 -0.9486832980505138)
>
>
>