Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

ACL bug in (tanh x) ?

6 views
Skip to first unread message

Daniel Buenzli

unread,
Jun 8, 2000, 3:00:00 AM6/8/00
to
Hello,

Is this an ACL bug ?

USER(15): (tanh 92.0)
#.EXCL::*NAN-SINGLE*

Daniel


Frode Vatvedt Fjeld

unread,
Jun 8, 2000, 3:00:00 AM6/8/00
to
Daniel Buenzli <Daniel....@studi.epfl.ch> writes:

> Is this an ACL bug ?
>
> USER(15): (tanh 92.0)
> #.EXCL::*NAN-SINGLE*

It seems to me to be a case of somewhat poor implementation, probably
rooted in this:

USER(93): (/ (- (exp 92) (exp -92)) (+ (exp 92) (exp -92)))
#.EXCL::*NAN-SINGLE*
USER(94): (exp 92.0)
#.EXCL::*INFINITY-SINGLE*

ACL seems to max out at about (exp 88), the same as CMUCL, but in
contrast to CMUCL there is no floating-point exception being
raised. Interestingly, CMUCL's implementation of TANH is smart enough
to avoid the overflow.

Since EXP and friends are specified to return a "number", I guess a
clever implementation _could_ detect the overflow and return an
integer (big-num) rather than failing, although I'm not sure if that's
desirable.

The problem is easily avoided though, as (TANH x) is indistinguishable
from 1.0 for all x>10 or so.

--
Frode Vatvedt Fjeld

William Deakin

unread,
Jun 8, 2000, 3:00:00 AM6/8/00
to

Daniel Buenzli wrote:

> USER(15): (tanh 92.0)
> #.EXCL::*NAN-SINGLE*

What value do you expect tanh 92.0 to give you?

Uhhh, scratches head, gets a sharp shooting pain, iirc tahn = (exp(x) -
exp(-x))/(exp(x)+exp(-x))) I would expect to tend to 1 (since exp(92) is
a large number). So in theory I would expect tanh 92.0 to return
1.0000000(and maybe some fiddly bits). However, because exp(92) is so
bloody big I would be not suprised if it didn't.

Cheers,

:) will

William Deakin

unread,
Jun 8, 2000, 3:00:00 AM6/8/00
to
Having spent five more minutes on this:

tanh(x) is approximately (1-y+y^2+...) where y = exp(-2x) so forget the
fiddly bits as the first-order error term is ~ exp(-184).

Hey ho.

:) will


Erik Naggum

unread,
Jun 8, 2000, 3:00:00 AM6/8/00
to
* Daniel Buenzli <Daniel....@studi.epfl.ch>

| Is this an ACL bug ?

Send mail to <bu...@franz.com>.

#:Erik
--
If this is not what you expected, please alter your expectations.

Tim Bradshaw

unread,
Jun 8, 2000, 3:00:00 AM6/8/00
to
* Daniel Buenzli wrote:
> Hello,

> Is this an ACL bug ?

> USER(15): (tanh 92.0)
> #.EXCL::*NAN-SINGLE*

I think it probably is. I imagine what's happening is they're using
some formula using e^x and running out of single-float range, even
though tanh is nowhere near out of range at that point. I'd report it
to bu...@franz.com


Daniel Buenzli

unread,
Jun 8, 2000, 3:00:00 AM6/8/00
to
Thanks .

Daniel


Raymond Toy

unread,
Jun 8, 2000, 3:00:00 AM6/8/00
to
>>>>> "Frode" == Frode Vatvedt Fjeld <fro...@acm.org> writes:

Frode> Daniel Buenzli <Daniel....@studi.epfl.ch> writes:
>> Is this an ACL bug ?
>>
>> USER(15): (tanh 92.0)
>> #.EXCL::*NAN-SINGLE*

[snip]

Frode> ACL seems to max out at about (exp 88), the same as CMUCL, but in
Frode> contrast to CMUCL there is no floating-point exception being
Frode> raised. Interestingly, CMUCL's implementation of TANH is smart enough
Frode> to avoid the overflow.

Well, in all ports of CMUCL tanh calls out to the tanh in your C math
library. So if tanh in your C library is broken, tanh in CMUCL is
broken.

Ray

Tim Bradshaw

unread,
Jun 8, 2000, 3:00:00 AM6/8/00
to
* Frode Vatvedt Fjeld wrote:

> ACL seems to max out at about (exp 88), the same as CMUCL, but in

> contrast to CMUCL there is no floating-point exception being

> raised. Interestingly, CMUCL's implementation of TANH is smart enough

> to avoid the overflow.

I think it's running out of single-float range. I don't think it
should though, since tanh is perfectly well-defined there.

> Since EXP and friends are specified to return a "number", I guess a
> clever implementation _could_ detect the overflow and return an
> integer (big-num) rather than failing, although I'm not sure if that's
> desirable.

No, it's not, in fact I think it's not allowed -- the numerical
contagion rules mean that (tanh x) should be of the same type as X (I
think). Certainly this, or something like it, would need to be the
case to allow the compiler to generate reasonable floating point code.

--tim


Daniel Buenzli

unread,
Jun 8, 2000, 3:00:00 AM6/8/00
to bu...@franz.com
I forgot to tell you the funny thing :

USER(1): (tanh 709)
#.EXCL::*NAN-SINGLE*
USER(2): (tanh 710)
1.0
USER(3): (tanh 2343254)
1.0

In fact it doesn't work from 89 to 709.

(Sun0s 5.7 acl-5.0)


Tim Bradshaw

unread,
Jun 8, 2000, 3:00:00 AM6/8/00
to
* Daniel Buenzli wrote:
> I forgot to tell you the funny thing :
> USER(1): (tanh 709)
> #.EXCL::*NAN-SINGLE*
> USER(2): (tanh 710)
> 1.0
> USER(3): (tanh 2343254)
> 1.0

> In fact it doesn't work from 89 to 709.

Cool!

CL-USER(2): (exp 709d0)
8.218407461554972d+307
CL-USER(3): (exp 710d0)
#.excl::*infinity-double*

So they've got a test in to stop it dying through overflow, but the
test assumes doubles, and it overflows with singles much earlier.
(I guess the test is something like `if it's greater than this just
return 1 coerced to the approprate type').

--tim


Erik Naggum

unread,
Jun 8, 2000, 3:00:00 AM6/8/00
to
* Tim Bradshaw <t...@cley.com>

| So they've got a test in to stop it dying through overflow, but the
| test assumes doubles, and it overflows with singles much earlier.
| (I guess the test is something like `if it's greater than this just
| return 1 coerced to the approprate type').

This is all bogus. (tanh x) is defined as (/ (sinh x) (cosh x)),
and those are defined as (/ (+/- (exp x) (exp (- x))) 2), but (exp
x) doesn't do a test, it bloats the value to double-float, computes
the value, then abbreviates it to single-float, which fails for a
whole truckload of double-floats, naturally. The NaN-single result
is simply that of of (/ infinity infinity).

I don't have an equally good explanation for the 1.0 result, which I
actually don't get on my Intel Pentium III running Linux. *sigh*

Tim Bradshaw

unread,
Jun 8, 2000, 3:00:00 AM6/8/00
to
* Erik Naggum wrote:

> I don't have an equally good explanation for the 1.0 result, which I
> actually don't get on my Intel Pentium III running Linux. *sigh*

That 1.0 result for numbers where (exp x) would overflow for doubles
was all I was trying to explain though. (I don't get it either
actually).

--tim


Jeff Greif

unread,
Jun 9, 2000, 3:00:00 AM6/9/00
to
When (exp (* -2 x)) < (expt 2 (- n)) where n is the number of bits of
precision of the floating point number, you can simply return the result
1.0 for tanh x, because you compute (tanh x) using (/ (- 1 (exp (- (* 2
x)))) (+ 1 (exp (- (* 2 x))))) instead of (/ (- (exp x) (exp (- x))) (+
(exp x) (exp (- x))))). The underflow of (exp (- (* 2 x))) is no
problem, and the result is 1.0.

Jeff

Daniel Buenzli wrote:

> Hello,

0 new messages