Is this an ACL bug ?
USER(15): (tanh 92.0)
#.EXCL::*NAN-SINGLE*
Daniel
> 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
> 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
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
Send mail to <bu...@franz.com>.
#:Erik
--
If this is not what you expected, please alter your expectations.
> 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
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
> 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
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)
> 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
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*
> 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
Daniel Buenzli wrote:
> Hello,