# define DBL_DIG OVR_DBL_DIG
#else
/* The following is all to get DBL_DIG, in order to pick a nice
- default value for printing floating point numbers in Gconvert.
- (see config.h)
+ default value for printing floating point numbers in Gconvert
+ (see config.h). (It also has other uses, such as figuring out if
+ a given precision of printing can be done with a double instead of
+ a long double - Allen).
*/
#ifdef I_LIMITS
#include <limits.h>
* necessary to do so. - Allen <allens@cpan.org>
*/
-#if defined(I_VALUES)
-# if !defined(USE_LONG_DOUBLE) || defined(HAS_LDBL_SPRINTF_BUG)
-# if (!defined(DBL_MIN) || !defined(DBL_MAX))
-# include <values.h>
-# if defined(MAXDOUBLE) && !defined(DBL_MAX)
-# define DBL_MAX MAXDOUBLE
-# endif
-# if defined(MINDOUBLE) && !defined(DBL_MIN)
-# define DBL_MIN MINDOUBLE
-# endif
-# endif
-# endif
+#ifdef I_LIMITS
+# include <limits.h>
#endif
+#ifdef I_VALUES
+# if !(defined(DBL_MIN) && defined(DBL_MAX) && defined(I_LIMITS))
+# include <values.h>
+# if defined(MAXDOUBLE) && !defined(DBL_MAX)
+# define DBL_MAX MAXDOUBLE
+# endif
+# if defined(MINDOUBLE) && !defined(DBL_MIN)
+# define DBL_MIN MINDOUBLE
+# endif
+# endif
+#endif /* defined(I_VALUES) */
+
typedef NVTYPE NV;
#ifdef I_IEEEFP
# ifdef DBL_EPSILON
# define NV_EPSILON DBL_EPSILON
# endif
-# ifdef DBL_MAX
+# ifdef DBL_MAX /* XXX Does DBL_MAX imply having DBL_MIN? */
# define NV_MAX DBL_MAX
# define NV_MIN DBL_MIN
# else
/* rumor has it that Win32 has _fpclass() */
+/* SGI has fpclassl... but not with the same result values,
+ * and it's via a typedef (not via #define), so will need to redo Configure
+ * to use. Not worth the trouble, IMO, at least until the below is used
+ * more places. Also has fp_class_l, BTW, via fp_class.h. Feel free to check
+ * with me for the SGI manpages, SGI testing, etcetera, if you want to
+ * try getting this to work with IRIX. - Allen <allens@cpan.org> */
+
#if !defined(Perl_fp_class) && (defined(HAS_FPCLASS)||defined(HAS_FPCLASSL))
# ifdef I_IEEFP
# include <ieeefp.h>
* it is however best to use the native implementation of atof.
* You can experiment with using your native one by -DUSE_PERL_ATOF=0.
* Some good tests to try out with either setting are t/base/num.t,
- * t/op/numconvert.t, and t/op/pack.t. */
+ * t/op/numconvert.t, and t/op/pack.t. Note that if using long doubles
+ * you may need to be using a different function than atof! */
#ifndef USE_PERL_ATOF
# ifndef _UNICOS
#ifdef I_LIMITS /* Needed for cast_xxx() functions below. */
# include <limits.h>
-#else
-#ifdef I_VALUES
-# include <values.h>
-#endif
#endif
+/* Included values.h above if necessary; still including limits.h down here,
+ * despite doing above, because math.h might have overriden... XXX - Allen */
/*
* Try to figure out max and min values for the integral types. THE CORRECT
}
if (!args && svix < svmax && DO_UTF8(*svargs))
- has_utf8 = TRUE;
+ has_utf8 = TRUE;
patend = (char*)pat + patlen;
for (p = (char*)pat; p < patend; p = q) {
bool is_utf8 = FALSE; /* is this item utf8? */
#ifdef HAS_LDBL_SPRINTF_BUG
/* This is to try to fix a bug with irix/nonstop-ux/powerux and
- with sfio - Allen <easmith@beatrice.rutgers.edu> */
+ with sfio - Allen <allens@cpan.org> */
bool fix_ldbl_sprintf_bug = FALSE;
#endif
-
+
char esignbuf[4];
U8 utf8buf[UTF8_MAXLEN+1];
STRLEN esignlen = 0;
* NV_DIG: mantissa takes than many decimal digits.
* Plus 32: Playing safe. */
char ebuf[IV_DIG * 4 + NV_DIG + 32];
- /* large enough for "%#.#f" --chip */
+ /* large enough for "%#.#f" --chip */
/* what about long double NVs? --jhi */
SV *vecsv = Nullsv;
#endif
case 'l':
#if defined(HAS_QUAD) || defined(HAS_LONG_DOUBLE)
- if (*(q + 1) == 'l') { /* lld, llf */
+ if (*(q + 1) == 'l') { /* lld, llf */
intsize = 'q';
q += 2;
break;
nv = (args && !vectorize) ?
#if LONG_DOUBLESIZE > DOUBLESIZE
intsize == 'q' ?
- va_arg(*args, long double) :
- va_arg(*args, double)
+ va_arg(*args, long double) :
+ va_arg(*args, double)
#else
- va_arg(*args, double)
+ va_arg(*args, double)
#endif
: SvNVx(argsv);
#ifdef HAS_LDBL_SPRINTF_BUG
/* This is to try to fix a bug with irix/nonstop-ux/powerux and
- with sfio - Allen <easmith@beatrice.rutgers.edu> */
- if ((intsize == 'q') && (c == 'f') &&
-#ifdef HAS_LDBL_SPRINTF_BUG_LESS1
-/* Only happens between -1 and 1 ??? - Allen */
- ((nv < 1L) && (nv > -1L)) &&
-#endif
- (need < DBL_DIG)) { /* it's going to be short enough that
- long double precision is not needed */
-
- if ((nv <= 0L) && (nv >= -0L)) {
- fix_ldbl_sprintf_bug = TRUE; /* Easiest */
- } else {
- /* SGI has fpclassl... but not with the same result values,
- and it's via a typedef, so will need to redo Configure
- to use. Not worth the trouble IMO. Also has fp_class_l,
- BTW, via fp_class.h - Allen */
-
- /* #if defined(HAS_FPCLASSL) && defined(USE_LONG_DOUBLE) */
- /* if (Perl_fp_class_zero((long double)nv)) { */
- /* fix_ldbl_sprintf_bug = TRUE; */ /* Easiest */
- /* } elsif (Perl_fp_class_norm((long double)nv)) { */
- /* #endif */
-#if !defined(DBL_MIN) || !defined(HAS_LDBL_SPRINTF_BUG_LESS1)
-# ifdef DBL_MAX
-# define MY_DBL_MAX DBL_MAX
-# else /* XXX guessing! HUGE_VAL may be defined as infinity, so not using */
-# if DOUBLESIZE >= 8
-# define MY_DBL_MAX 1.7976931348623157E+308L
+ with sfio - Allen <allens@cpan.org> */
+
+# ifdef DBL_MAX
+# define MY_DBL_MAX DBL_MAX
+# else /* XXX guessing! HUGE_VAL may be defined as infinity, so not using */
+# if DOUBLESIZE >= 8
+# define MY_DBL_MAX 1.7976931348623157E+308L
+# else
+# define MY_DBL_MAX 3.40282347E+38L
+# endif
+# endif
+
+# ifdef HAS_LDBL_SPRINTF_BUG_LESS1 /* only between -1L & 1L - Allen */
+# define MY_DBL_MAX_BUG 1L
# else
-# define MY_DBL_MAX 3.40282347E+38L
+# define MY_DBL_MAX_BUG MY_DBL_MAX
# endif
-# endif
-#endif /* !defined(DBL_MIN) || !defined(HAS_LDBL_SPRINTF_BUG_LESS1 */
-#ifndef HAS_LDBL_SPRINTF_BUG_LESS1
- if ((nv < MY_DBL_MAX) && (nv > -MY_DBL_MAX)) {
-#endif
+# ifdef DBL_MIN
+# define MY_DBL_MIN DBL_MIN
+# else /* XXX guessing! -Allen */
+# if DOUBLESIZE >= 8
+# define MY_DBL_MIN 2.2250738585072014E-308L
+# else
+# define MY_DBL_MIN 1.17549435E-38L
+# endif
+# endif
-#ifdef DBL_MIN
-# define MY_DBL_MIN DBL_MIN
-#else /* XXX guessing! -Allen */
-# if DOUBLESIZE >= 8
-# define MY_DBL_MIN 2.2250738585072014E-308L
-# else
-# define MY_DBL_MIN 1.17549435E-38L
-# endif
-#endif
- if (((nv > 0L) && (nv >= MY_DBL_MIN)
-#ifndef DBL_MIN
- && ((long double)1/MY_DBL_MAX <= nv)
-#endif
- ) || ((nv < -0L) && (nv <= -MY_DBL_MIN)
-#ifndef DBL_MIN
- && (-(long double)1/MY_DBL_MAX >= nv)
+ if ((intsize == 'q') && (c == 'f') &&
+ ((nv < MY_DBL_MAX_BUG) && (nv > -MY_DBL_MAX_BUG)) &&
+ (need < DBL_DIG)) {
+ /* it's going to be short enough that
+ * long double precision is not needed */
+
+ if ((nv <= 0L) && (nv >= -0L))
+ fix_ldbl_sprintf_bug = TRUE; /* 0 is 0 - easiest */
+ else {
+ /* would use Perl_fp_class as a double-check but not
+ * functional on IRIX - see perl.h comments */
+
+ if ((nv >= MY_DBL_MIN) || (nv <= -MY_DBL_MIN)) {
+ /* It's within the range that a double can represent */
+#if defined(DBL_MAX) && !defined(DBL_MIN)
+ if ((nv >= ((long double)1/DBL_MAX)) ||
+ (nv <= (-(long double)1/DBL_MAX)))
#endif
- )) {
- /* It's within the range that a double can represent */
- fix_ldbl_sprintf_bug = TRUE;
+ fix_ldbl_sprintf_bug = TRUE;
}
-#undef MY_DBL_MIN
-#ifndef HAS_LDBL_SPRINTF_BUG_LESS1
- }
-#endif
-#if !defined(DBL_MIN) || !defined(HAS_LDBL_SPRINTF_BUG_LESS1)
-# undef MY_DBL_MAX
-#endif
-/* #if defined(HAS_FPCLASSL) && defined(USE_LONG_DOUBLE) */
-/* } */
-/* #endif */
- }
- if (fix_ldbl_sprintf_bug == TRUE) {
- double temp;
-
- intsize = 0;
- temp = (double)nv;
- nv = (NV)temp;
- }
+ }
+ if (fix_ldbl_sprintf_bug == TRUE) {
+ double temp;
+
+ intsize = 0;
+ temp = (double)nv;
+ nv = (NV)temp;
+ }
}
+
+# undef MY_DBL_MAX
+# undef MY_DBL_MAX_BUG
+# undef MY_DBL_MIN
+
#endif /* HAS_LDBL_SPRINTF_BUG */
need += 20; /* fudge factor */