Hi,
I have following problem:
I want to prevent overflows by the expt function. Therfore i tested if the
value of (expt base power) would cause an overflow. When an overflow would
occure i want to give back my self defined *maxValue* with the right sign.
So I returned (* (expt (signum base) power) *maxValue*). But unfortunally I
always got complex numbers back. Can anybody tell my a way how to prevent
those complex numbers?
Thanks in advance
Carsten
--
To mail me remove "_nospam" in my email address
In article <············@tyfon.itea.ntnu.no>,
Carsten Gester <···············@gmx.net> wrote:
>Hi,
>I have following problem:
>I want to prevent overflows by the expt function. Therfore i tested if the
>value of (expt base power) would cause an overflow. When an overflow would
>occure i want to give back my self defined *maxValue* with the right sign.
>So I returned (* (expt (signum base) power) *maxValue*). But unfortunally I
>always got complex numbers back. Can anybody tell my a way how to prevent
>those complex numbers?
Raising a negative number to a non-integer power will always result in a
complex number. I'm not sure why you're raising the signum to any power,
though; I think you want to return (* (signum base) *maxValue*).
--
Barry Margolin, ······@genuity.net
Genuity, Woburn, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
In article <············@tyfon.itea.ntnu.no>, Carsten Gester wrote:
> Hi,
> I have following problem:
> I want to prevent overflows by the expt function. Therfore i tested if the
> value of (expt base power) would cause an overflow. When an overflow would
> occure i want to give back my self defined *maxValue* with the right sign.
> So I returned (* (expt (signum base) power) *maxValue*). But unfortunally I
> always got complex numbers back. Can anybody tell my a way how to prevent
> those complex numbers?
I am not sure how to detect overflow, I'd probably try to prevent
it in the first place, but you can get rid of the complex numbers
easily by not computing -1^{2.3} or some such because that would
be exp(log (-1^2.3)) = exp(2.3 log(-1)) = exp(2.3 i pi).
Regards,
--
Nils Goesche
"Don't ask for whom the <CTRL-G> tolls."
PGP key ID 0x42B32FC9
Thanks to every one,
I found a solution. My over- and underflow proof power function looks now
like this:
(defun nthRoot (x n)
(if (> x 0)
(exp (/ (ln x) n))
0))
(defun gevenp (b p)
"Returns 1 if p is even otherwise (signum b)"
(if (= 0 (mod p 2)) 1 (signum b)))
(defun gexp (base power)
"Secure exponential function: prevents floating point over- and
underflows cau by large or small numbers of power and some bases near
zero"
(defun sub_gexp (base power)
"Prevent over- and underflows"
(cond
;; if power is a very large number (e.g 10E10) an overflow can occure
((and (> power 0) (not (= base 0))
(> (log (abs base) *maxValue*) (/ 1 power)))
(* (gevenp base power) *maxValue*))
;; if power is a very small number (e.g. -10E10) an underflow can
occure
((and (< power 0) (not (= base 0))
(< (log (abs base) *minValue*) (/ 1 power)))
(* (gevenp base power) *minValue*))
;;if the base is near zero and the power a very large number (e.g.
10E24) a ((and (> power 1) (<= (abs base) (nthRoot *minValue* power)))
(* (gevenp base power) *minValue*))
;;if the base is near zero and the power a very small number (e.g.
-10E24)
((and (< power -1) (<= (abs base) (nthRoot *minValue* power)))
(* (gevenp base power) *minValue*))
(t (expt base power))))
(cond ((and (= base 0) (< power 0)) 0) ; prevent division by zero caused
by an ((= power 0) 1) ; if the exponent is 0 return 1
;; if the base is smaller than zero round the exponent to prevent
comple ((< base 0) (sub_gexp base (round power)))
;; otherwise compute base to the power of power without over- or
underfl (t (sub_gexp base power))))
--
To mail me remove "_nospam" in my email address
In article <············@tyfon.itea.ntnu.no>, Carsten Gester wrote:
> Thanks to every one,
> I found a solution. My over- and underflow proof power function looks now
> like this:
[snip]
> (defun gexp (base power)
> "Secure exponential function: prevents floating point over- and
> underflows cau by large or small numbers of power and some bases near
> zero"
>
> (defun sub_gexp (base power)
> "Prevent over- and underflows"
Please note that defun defines a new function in the global environment
no matter where it occurs. When you want a local function, use flet
or labels instead.
Regards,
--
Nils Goesche
"Don't ask for whom the <CTRL-G> tolls."
PGP key ID 0x42B32FC9
In article <············@tyfon.itea.ntnu.no>,
Carsten Gester <···············@gmx.net> wrote:
> (defun sub_gexp (base power)
> "Prevent over- and underflows"
> (cond
> ;; if power is a very large number (e.g 10E10) an overflow can occure
> ((and (> power 0) (not (= base 0))
> (> (log (abs base) *maxValue*) (/ 1 power)))
Why not use a condition handler?
--
Barry Margolin, ······@genuity.net
Genuity, Woburn, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
Barry Margolin <······@genuity.net> writes:
> In article <············@tyfon.itea.ntnu.no>,
> Carsten Gester <···············@gmx.net> wrote:
> > (defun sub_gexp (base power)
> > "Prevent over- and underflows"
> > (cond
> > ;; if power is a very large number (e.g 10E10) an overflow can occure
> > ((and (> power 0) (not (= base 0))
> > (> (log (abs base) *maxValue*) (/ 1 power)))
>
> Why not use a condition handler?
That was my first thought, too, but at least Lispworks doesn't
seem to throw the FLOATING-POINT-OVERFLOW condition but returns
an NaN instead. Do I have to enable it somehow first? Or should
I submit a bug report?
Regards,
--
Nils Goesche
Ask not for whom the <CONTROL-G> tolls.
PGP key ID 0xC66D6E6F