develooper Front page | perl.vmsperl | Postings from June 2002

Re: [PATCH #2] Re: [PATCH] numeric.c:S_mulexp10 -- quit when you can

Thread Previous | Thread Next
From:
Hugo van der Sanden
Date:
June 19, 2002 14:02
Subject:
Re: [PATCH #2] Re: [PATCH] numeric.c:S_mulexp10 -- quit when you can
Message ID:
200206192104.g5JL4cU15041@crypt.compulink.co.uk
"Craig A. Berry" <craigberry@mac.com> wrote:
:Unfortunately it had no effect on the problem, which seems to occur not in 
:the loop you patched but further down in the call [...]

Ah, I've been looking at it all wrong. The conditional code in mulexp10
was all wrong; the attached (to be applied _instead_ of my previous
patch) may improve things.

This also removes the separate UNICOS block, which was a duplicate since
the previous block had had its condition extended.

I also realised it was slightly easier to test than I'd thought - I just
replaced the conditional with '#if 1', and all tests passed here.

Hugo
--- numeric.c.old	Sun Jun  9 18:55:23 2002
+++ numeric.c	Wed Jun 19 22:00:44 2002
@@ -727,10 +727,6 @@
 
     if (exponent == 0)
 	return value;
-    else if (exponent < 0) {
-	negative = 1;
-	exponent = -exponent;
-    }
 
     /* On OpenVMS VAX we by default use the D_FLOAT double format,
      * and that format does not have *easy* capabilities [1] for
@@ -743,11 +739,6 @@
      *
      * [1] Trying to establish a condition handler to trap floating point
      *     exceptions is not a good idea. */
-    /* UNICOS fp is similarly non-IEEE. */
-#if ((defined(VMS) && !defined(__IEEE_FP)) || defined(_UNICOS)) && defined(NV_MAX_10_EXP)
-    if ((log10(value) + exponent) >= (NV_MAX_10_EXP))
-        return negative ? 0.0 : NV_MAX;
-#endif
 
     /* In UNICOS and in certain Cray models (such as T90) there is no
      * IEEE fp, and no way at all from C to catch fp overflows gracefully.
@@ -756,12 +747,28 @@
      * disable *all* floating point interrupts, a little bit too large
      * a hammer.  Therefore we need to catch potential overflows before
      * it's too late. */
-#if defined(_UNICOS) && defined(NV_MAX_10_EXP)
-    if (!negative &&
-	(log10(value) + exponent) >= NV_MAX_10_EXP)
-        return NV_MAX;
+
+#if ((defined(VMS) && !defined(__IEEE_FP)) || defined(_UNICOS)) && defined(NV_MAX_10_EXP)
+    STMT_START {
+	NV exp_v = log10(value);
+	if (exponent >= NV_MAX_10_EXP || exponent + exp_v >= NV_MAX_10_EXP)
+	    return NV_MAX;
+	if (exponent < 0) {
+	    if (-(exponent + exp_v) >= NV_MAX_10_EXP)
+		return 0.0;
+	    while (-exponent >= NV_MAX_10_EXP) {
+		/* combination does not overflow, but 10^(-exponent) does */
+		value /= 10;
+		++exponent;
+	    }
+	}
+    } STMT_END
 #endif
 
+    if (exponent < 0) {
+	negative = 1;
+	exponent = -exponent;
+    }
     for (bit = 1; exponent; bit <<= 1) {
 	if (exponent & bit) {
 	    exponent ^= bit;

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About