Email list hosting service & mailing list manager

comments on latest draft William D Clinger (04 Jun 2017 05:35 UTC)
Re: comments on latest draft William D Clinger (05 Jun 2017 18:39 UTC)
Re: comments on latest draft William D Clinger (07 Jun 2017 03:50 UTC)
Re: comments on latest draft Bradley Lucier (07 Jun 2017 19:55 UTC)
Re: comments on latest draft William D Clinger (07 Jun 2017 23:25 UTC)
Re: comments on latest draft Bradley Lucier (08 Jun 2017 01:09 UTC)
Re: comments on latest draft William D Clinger (09 Jun 2017 15:19 UTC)
Re: comments on latest draft Bradley Lucier (09 Jun 2017 17:11 UTC)
Re: comments on latest draft Bradley Lucier (09 Jun 2017 17:18 UTC)

Re: comments on latest draft Bradley Lucier 09 Jun 2017 17:11 UTC

On 06/09/2017 11:19 AM, William D Clinger wrote:
> But I think the following definition is correct:
>
> (define fl+*
>    (flop3 'fl+*
>           (lambda (x y z)
>             (cond ((and (flfinite? x) (flfinite? y) (flfinite? z))
>                    (let ((x (exact x))
>                          (y (exact y))
>                          (z (exact z)))
>                      (flonum (+ (* x y) z))))
>                   (else
>                    (fl+ (fl* x y) z))))))

I think you want a tweak.  I ran the following in Gambit:

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define fma
   (c-lambda (double double double)
             double
             "fma"))

(define exact inexact->exact)
(define flonum inexact->exact)

(define fl+*
   (lambda (x y z)
     (cond ((and (flfinite? x) (flfinite? y) (flfinite? z))
            (let ((x (exact x))
                  (y (exact y))
                  (z (exact z)))
              (flonum (+ (* x y) z))))
           (else
            (fl+ (fl* x y) z)))))

(define fl+*-new
   (lambda (x y z)
     (if (and (flfinite? x)
              (flfinite? y))
         (if (flfinite? z)
             (flonum (+ (* x y) z))
             z)
         (fl+ (fl* x y) z))))

(define large       ;; large is finite, (fl* 2. large) overflows
   (do ((i 1. (* 2. i)))
       ((infinite? (* 2. i))
        (* 1.5 i))))

(pp (fma large 2. -inf.0))

(pp (fl+* large 2.0 -inf.0))

(pp (fl+*-new large 2.0 -inf.0))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

and got

firefly:~> gsc -exe fma
firefly:~> ./fma
-inf.0
+nan.0
-inf.0

So you want to catch the case where x and y are finite, z is infinite,
and x*y overflows to an infinity of opposite sign to z (you want z
returned instead of a NaN).

Brad