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