From: Kenneth P. Turvey
Subject: Handling a floating point underflow
Date: 
Message-ID: <slrn696pjq.4n3.kturvey@pug1.sprocketshop.com>
I have written some code that on that includes an exponential function
within a loop that may on occasion take on a form that looks something
like this:

(exp (- (/ 1000 .01)))

This program runs fine under gcl, but when I move it to a faster
machine to run it under clisp I am greeted with the following message:

*** - floating point underflow

and the program goes to the debugger.  I understand the source of the
problem, but I would like clisp to handle it the same way that gcl
does: just return 0 for the form.

Is there some way that I can trap this error under clisp and have it
return a zero.

I am new to lisp, so please forgive me if the answer to this question
is obvious to you (and should be to me). 

-- 
Kenneth P. Turvey <·······@pug1.SprocketShop.com> 

The strongest reason for the people to retain their right to keep and
bear arms is,  as a last resort, to protect themselves against tyranny
in government.
	-- Thomas Jefferson

From: Kent M Pitman
Subject: Re: Handling a floating point underflow
Date: 
Message-ID: <sfw3ejwpcjl.fsf@world.std.com>
·······@pug1.sprocketshop.com (Kenneth P. Turvey) writes:

> Is there some way that I can trap this error under clisp and have it
> return a zero.

I can't speak for clisp specifically, but in general in CL it will work
to do:

  (handler-case (exp (- (/ 1000 .01)))
    (floating-point-underflow 0.0))

If you're in a tight loop, it may be expensive to set up the handler.
An unspecified amount of consing might occur.  If too much does
happen, you could try something like this around a large body of code:

 (defvar *fpu-handler-enabled* nil)

 (defmacro with-result-or (value result)
   (let ((temp (gensym)))
     `(let ((,temp ,value))
        (block ,temp
	  (catch 'fpu-handler
	    (let ((*fpu-handler-enabled* t))
	      (return-from ,temp ,result)))
	  ,temp))))

 (handler-bind ((arithmetic-error
		  #'(lambda (c) 
		      (when *fpu-handler-enabled*
			(throw 'fpu-handler t)))))
   ...large body of code...)

The body of code might use 
  (with-result-or 0.0 (exp (- / 1000 .01)))

I had trouble testing this because LispWorks doesn't do a float underflow
in your example and I was too lazy to find something else that does.
Hopefully the code works, but if it doesn't seem to, ask me.
From: Hrvoje Niksic
Subject: Re: Handling a floating point underflow
Date: 
Message-ID: <kigsorvi5l5.fsf@jagor.srce.hr>
·······@pug1.sprocketshop.com (Kenneth P. Turvey) writes:

> (exp (- (/ 1000 .01)))
> 
> This program runs fine under gcl, but when I move it to a faster
> machine to run it under clisp I am greeted with the following message:
> 
> *** - floating point underflow
> 
> and the program goes to the debugger.  I understand the source of the
> problem, but I would like clisp to handle it the same way that gcl
> does: just return 0 for the form.
> 
> Is there some way that I can trap this error under clisp and have it
> return a zero.

CMU CL returns 0.0 for that example.  Emacs signals the underflow.

The idea is that you should set up a handler for the error.  In Emacs
Lisp, you would do something like this:

(condition-case nil
    (exp (- (/ 1000 .01)))
  (underflow-error 0.0))

Glancing at CL hyperspecs, I assume `handler-bind' should suit your
purpose.

<URL:http://www.harlequin.com/education/books/HyperSpec/Body/mac_handler-bind.html#handler-bind>

-- 
Hrvoje Niksic <·······@srce.hr> | Student at FER Zagreb, Croatia
--------------------------------+--------------------------------
Ask not for whom the <CONTROL-G> tolls.
From: Raymond Toy
Subject: Re: Handling a floating point underflow
Date: 
Message-ID: <4nafe2zp0l.fsf@rtp.ericsson.se>
>>>>> "Hrvoje" == Hrvoje Niksic <·······@srce.hr> writes:

    Hrvoje> ·······@pug1.sprocketshop.com (Kenneth P. Turvey) writes:
    >> (exp (- (/ 1000 .01)))
    >> 
    >> This program runs fine under gcl, but when I move it to a faster
    >> machine to run it under clisp I am greeted with the following message:
    >> 
    >> *** - floating point underflow
    >> 
    >> and the program goes to the debugger.  I understand the source of the
    >> problem, but I would like clisp to handle it the same way that gcl
    >> does: just return 0 for the form.
    >> 
    >> Is there some way that I can trap this error under clisp and have it
    >> return a zero.

    Hrvoje> CMU CL returns 0.0 for that example.

That's because your version has the underflow trap turned off.  Some
architectures like x86 have almost all FP traps off. On Solaris, all
traps are on.

Ray
From: Bruno Haible
Subject: Re: Handling a floating point underflow
Date: 
Message-ID: <1807p1523@clisp.cons.org>
Kenneth P. Turvey <·······@pug1.sprocketshop.com> wrote:
>
> (exp (- (/ 1000 .01)))
>
> This program runs fine under gcl, but when I move it to a faster
> machine to run it under clisp I am greeted with the following message:
>
> *** - floating point underflow
>
> and the program goes to the debugger.  I understand the source of the
> problem, but I would like clisp to handle it the same way that gcl
> does: just return 0 for the form.

CLISP has a special macro for dealing with this:

   (without-floating-point-underflow (exp (- (/ 1000 .01))))

returns 0.0. This is documented in clisp's implementation notes.
It is sufficient to put this macro once around all the computation,
not around every call to `exp' and `*'.

Sorry for introducing a non-portable macro. Hope it helps nevertheless.

                    Bruno