Thanks to Brian Tillman's report of problems with an RC1 build on
VAX, I've discovered an issue in S_mulexp10 where it squares the
exponent again even after it's done iterating through the bits of the
exponent. This is particularly harmful with VMS's D_FLOAT double
format (the default on VAX) which has a maximum range of 1.7e38. For
example, when t/base/num.t tries to parse 1e34 at compile time, it
blows up because it tries to square 1e33 after it's already found the
correct result. And even smaller values have the same problem;
apparently 1e32 is the boundary:
$ mcr []miniperl -e "$a=1e31; print $a;"
1e+31
$ mcr []miniperl -e "$a=1e32; print $a;"
$ write sys$output f$message($status)
%SYSTEM-F-HPARITH, high performance arithmetic trap, Imask=!XL, Fmask=!XL,
summary=!XB, PC=!XH, PS=!XL
None of this matters particularly for systems using IEEE floating
point, but IEEE is not available on OpenVMS VAX and is optional on
OpenVMS Alpha. It looks like UNICOS could also be affected. The
patch below fixes the problem by exiting the loop once we know we've
finished examining (and clearing) all the bits of the exponent.
As far as speed impact, on average we'll probably test a 32-bit
integer for zero once or twice that we didn't do before but we're
guaranteed to save a floating point multiplication we don't need.
--- numeric.c;-0 Sat Jun 1 12:03:34 2002
+++ numeric.c Fri Jun 7 16:40:25 2002
@@ -765,10 +765,13 @@
for (bit = 1; exponent; bit <<= 1) {
if (exponent & bit) {
exponent ^= bit;
result *= power;
+ /* Floating point exceptions are supposed to be turned off,
+ * but if we're obviously done, don't risk another iteration.
+ */
+ if (exponent == 0) break;
}
- /* Floating point exceptions are supposed to be turned off. */
power *= power;
}
return negative ? value / result : value * result;
}
[end of patch]
--
________________________________________
Craig A. Berry
mailto:[EMAIL PROTECTED]
"... getting out of a sonnet is much more
difficult than getting in."
Brad Leithauser