Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 05 Jan 2000 08:38:11 -0800
From:      "Ronald F. Guilmette" <rfg@monkeys.com>
To:        Martin Cracauer <cracauer@cons.org>
Cc:        Markus Holmberg <saska@acc.umu.se>, freebsd-hackers@FreeBSD.ORG
Subject:   Re: Should -mieee-fp equal fpsetmask(0) to avoid SIGFPE on FreeBSD? 
Message-ID:  <91688.947090291@monkeys.com>
In-Reply-To: Your message of Wed, 05 Jan 2000 09:23:57 %2B0100. <20000105092356.A8100@cons.org> 

next in thread | previous in thread | raw e-mail | index | archive | help

I confess that I didn't look at the original Bugzilla bugreport on this
thing too closely, but...

In message <20000105092356.A8100@cons.org>, 
Martin Cracauer <cracauer@cons.org> wrote:

>> #define JSDOUBLE_IS_INT(d, i) (JSDOUBLE_IS_FINITE(d) && \
>> 	!JSDOUBLE_IS_NEGZERO(d) && ((d) == (i = (jsint)(d))))
>
>Ah, OK, this macro is a conversion where the undefined result of the
>(int)double_bigger_max_int is (intentionally) used as a speed hack of
>a range check.
>...
>While the result of 
>  (int)double_bigger_max_int
>is undefined, you will usually get an i that is filled with any
>integer value. If d was > INT_MAX, the == with return nil for any
>value of i. Hence the thing works if the programmer remembers only to
>use i if the macro return true.
>
>Beside the fact that I don't like this construction style-wise, I have
>two problems with it:
>
>1) In C, when an expression is undefined, *anything* may happen. You
>   cannot depend on the fact that the code behaves as if i was filled
>   with an integer at all. This is not ANSI C conformant. An
>   conformant ANSI C compiler may make assumptions about this code
>   that break it.

Ah!  Yea.  This is a DEFINITE problem.

>The alternative to this hack is a normal range check...
>...
>static inline int cra_is_int(const double d, int *const i)
>{
>  if (d <= (double)INT_MAX && d >= (double)INT_MIN) {
>    *i = (int)d;
>    return 1;
>  } else
>    return 0;
>}

The function shown above is indeed the correct solution/approach for
what Mozilla is trying to do here, for the reasons cited above.

But having said that, I also want to reiterate what I said before...

Yes, the existing Mozilla code should be fixed to perform the range
check in the manner that Martin Cracauer <cracauer@cons.org> has
shown above.  However the can-of-worms opened up by this whole
thread/discussion has revealed *two* bugs... one in the Mozilla
code (which Martin Cracauer <cracauer@cons.org> has correctly
described, diagnosed, and provided a solution for) and also, there
is still that annoying little deviation from the IEEE FP standard
that results from FreeBSD's failure to disable all IEEE FP traps
upon entry to main.

_Both_ bugs should be fixed.


-- rfg


P.S.  Actually, although Martin Cracauer's suggested replacement for
the existing Mozilla code is certainly better than what Mozilla is
using now, it may perhaps need to be slightly augmented with an
additional check to see if the value of `d' is a NaN prior to per-
forming the range check.  But I'm not even sure about that.  I'd
have to go and dredge my copy of IEEE 754 out of my files again to
find out what the results of <= and >= are in cases where one of
the operands is a NaN.  I think however that those operations are
perhaps required to return False in that case, in which case Martin
Cracauer's suggested Mozilla replacement code is just fine as it is.

And in any case, that is all a moot point anyway if it is known in
advance that `d' will not be a NaN.


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?91688.947090291>