negative = 1;
exponent = -exponent;
}
-#ifdef __VAX /* avoid %SYSTEM-F-FLTOVF_F sans VAXC$ESTABLISH */
-# if defined(__DECC_VER) && __DECC_VER <= 50390006
- /* __F_FLT_MAX_10_EXP - 5 == 33 */
+
+ /* On OpenVMS VAX we by default use the D_FLOAT double format,
+ * and that format does not have *easy* capabilities [1] for
+ * overflowing doubles 'silently' as IEEE fp does. We also need
+ * to support G_FLOAT on both VAX and Alpha, and though the exponent
+ * range is much larger than D_FLOAT it still doesn't do silent
+ * overflow. Therefore we need to detect early whether we would
+ * overflow (this is the behaviour of the native string-to-float
+ * conversion routines, and therefore of native applications, too).
+ *
+ * [1] Trying to establish a condition handler to trap floating point
+ * exceptions is not a good idea. */
+#if defined(VMS) && !defined(__IEEE_FP) && defined(NV_MAX_10_EXP)
if (!negative &&
- (log10(value) + exponent) >= (__F_FLT_MAX_10_EXP - 5))
+ (log10(value) + exponent) >= (NV_MAX_10_EXP))
return NV_MAX;
-# endif
#endif
-#if defined(__alpha) && defined(__unix__)
+
+ /* 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.
+ * There is something you can do if you are willing to use some
+ * inline assembler: the instruction is called DFI-- but that will
+ * 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) >= (DBL_MAX_10_EXP))
- return NV_INF;
+ (log10(value) + exponent) >= NV_MAX_10_EXP)
+ return NV_MAX;
#endif
+
for (bit = 1; exponent; bit <<= 1) {
if (exponent & bit) {
exponent ^= bit;
result *= power;
}
+ /* Floating point exceptions are supposed to be turned off. */
power *= power;
}
return negative ? value / result : value * result;