[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
gawk: use long double for AWKNUM when useful
From: |
Jean-Marc Saffroy |
Subject: |
gawk: use long double for AWKNUM when useful |
Date: |
Thu, 29 Apr 2010 01:24:11 +0200 (CEST) |
Hi (again),
In a previous life, I had suggested that defining AWKNUM as long double on
IA64 would be beneficial:
http://lists.gnu.org/archive/html/bug-gnu-utils/2005-04/msg00094.html
Recently I saw that gawk had only partial support for this. The patch
below uses AC_TYPE_LONG_DOUBLE_WIDER to test when long double is useful.
It also enables longdbl in the test suite, and adds a macro for a length
modifier to printf when required.
It is worth noting that HAVE_LONG_DOUBLE_WIDER == 1 on both x86 and
x86-64, so this may impact performance a bit; but I assume the benefit of
handling larger integral values is more important (to me it is).
The configury stuff that has to be regenerated is not included (I don't
have the exact same versions as in the archive). Patch is against 3.1.7.
Cheers,
Jean-Marc
--
address@hidden
diff --git a/array.c b/array.c
--- a/array.c
+++ b/array.c
@@ -776,7 +776,7 @@ static void
pr_node(NODE *n)
{
if ((n->flags & (NUMCUR|NUMBER)) != 0)
- printf("%g", n->numbr);
+ printf("%"NMOD"g", n->numbr);
else
printf("%.*s", (int) n->stlen, n->stptr);
}
diff --git a/awk.h b/awk.h
--- a/awk.h
+++ b/awk.h
@@ -308,17 +308,18 @@ extern double gawk_strtod();
/* ------------------ Constants, Structures, Typedefs ------------------ */
-#if 0
-/* This isn't right. Figure it out the right way for the next release */
#ifndef AWKNUM
-#ifdef LDBL_MANT_DIG
+#ifdef HAVE_LONG_DOUBLE_WIDER
#define AWKNUM long double
+#define NMOD "L" /* length modifier for printf */
#else
-#endif
+#define AWKNUM double
#endif
#endif
-#define AWKNUM double
+#ifndef NMOD
+#define NMOD "" /* length modifier for printf */
+#endif
#ifndef TRUE
/* a bit hackneyed, but what the heck */
@@ -1011,7 +1012,7 @@ extern int check_special P((const char *
extern void register_deferred_variable P((const char *name,
NODE *(*load_func)(void)));
/* builtin.c */
-extern double double_to_int P((double d));
+extern AWKNUM double_to_int P((AWKNUM d));
extern NODE *do_exp P((NODE *tree));
extern NODE *do_fflush P((NODE *tree));
extern NODE *do_index P((NODE *tree));
diff --git a/awkgram.y b/awkgram.y
--- a/awkgram.y
+++ b/awkgram.y
@@ -2717,13 +2717,13 @@ valinfo(NODE *n, FILE *fp)
pp_string_fp(fp, n->stptr, n->stlen, '"', FALSE);
fprintf(fp, ")\n");
} else if (n->flags & NUMBER)
- fprintf(fp, "number (%.17g)\n", n->numbr);
+ fprintf(fp, "number (%.17"NMOD"g)\n", n->numbr);
else if (n->flags & STRCUR) {
fprintf(fp, "string value (");
pp_string_fp(fp, n->stptr, n->stlen, '"', FALSE);
fprintf(fp, ")\n");
} else if (n->flags & NUMCUR)
- fprintf(fp, "number value (%.17g)\n", n->numbr);
+ fprintf(fp, "number value (%.17"NMOD"g)\n", n->numbr);
else
fprintf(fp, "?? flags %s\n", flags2str(n->flags));
}
diff --git a/builtin.c b/builtin.c
--- a/builtin.c
+++ b/builtin.c
@@ -411,8 +411,8 @@ out:
/* double_to_int --- convert double to int, used several places */
-double
-double_to_int(double d)
+AWKNUM
+double_to_int(AWKNUM d)
{
if (d >= 0)
d = Floor(d);
@@ -978,7 +978,7 @@ check_pos:
uval = (uintmax_t) arg->numbr;
#endif
if (do_lint && uval > 255) {
- lintwarn("[s]printf: value %g is too
big for %%c format",
+ lintwarn("[s]printf: value %"NMOD"g is
too big for %%c format",
arg->numbr);
}
cpbuf[0] = uval;
@@ -1044,7 +1044,7 @@ check_pos:
* is enough room in the buffer or not.
*/
while ((i = snprintf(cpbufs[1].buf,
- cpbufs[1].bufsize, "%.0f",
+ cpbufs[1].bufsize, "%.0"NMOD"f",
tmpval)) >=
cpbufs[1].bufsize) {
if (cpbufs[1].buf == cpbufs[1].stackbuf)
@@ -2840,11 +2840,11 @@ do_lshift(NODE *tree)
shift = force_number(s2);
if (do_lint) {
if (val < 0 || shift < 0)
- lintwarn(_("lshift(%lf, %lf): negative values will give
strange results"), val, shift);
+ lintwarn(_("lshift(%"NMOD"f, %"NMOD"f): negative values
will give strange results"), val, shift);
if (double_to_int(val) != val || double_to_int(shift) != shift)
- lintwarn(_("lshift(%lf, %lf): fractional values will be
truncated"), val, shift);
+ lintwarn(_("lshift(%"NMOD"f, %"NMOD"f): fractional
values will be truncated"), val, shift);
if (shift >= sizeof(uintmax_t) * CHAR_BIT)
- lintwarn(_("lshift(%lf, %lf): too large shift value
will give strange results"), val, shift);
+ lintwarn(_("lshift(%"NMOD"f, %"NMOD"f): too large shift
value will give strange results"), val, shift);
}
free_temp(s1);
@@ -2878,11 +2878,11 @@ do_rshift(NODE *tree)
shift = force_number(s2);
if (do_lint) {
if (val < 0 || shift < 0)
- lintwarn(_("rshift(%lf, %lf): negative values will give
strange results"), val, shift);
+ lintwarn(_("rshift(%"NMOD"f, %"NMOD"f): negative values
will give strange results"), val, shift);
if (double_to_int(val) != val || double_to_int(shift) != shift)
- lintwarn(_("rshift(%lf, %lf): fractional values will be
truncated"), val, shift);
+ lintwarn(_("rshift(%"NMOD"f, %"NMOD"f): fractional
values will be truncated"), val, shift);
if (shift >= sizeof(uintmax_t) * CHAR_BIT)
- lintwarn(_("rshift(%lf, %lf): too large shift value
will give strange results"), val, shift);
+ lintwarn(_("rshift(%"NMOD"f, %"NMOD"f): too large shift
value will give strange results"), val, shift);
}
free_temp(s1);
@@ -2916,9 +2916,9 @@ do_and(NODE *tree)
right = force_number(s2);
if (do_lint) {
if (left < 0 || right < 0)
- lintwarn(_("and(%lf, %lf): negative values will give
strange results"), left, right);
+ lintwarn(_("and(%"NMOD"f, %"NMOD"f): negative values
will give strange results"), left, right);
if (double_to_int(left) != left || double_to_int(right) !=
right)
- lintwarn(_("and(%lf, %lf): fractional values will be
truncated"), left, right);
+ lintwarn(_("and(%"NMOD"f, %"NMOD"f): fractional values
will be truncated"), left, right);
}
free_temp(s1);
@@ -2952,9 +2952,9 @@ do_or(NODE *tree)
right = force_number(s2);
if (do_lint) {
if (left < 0 || right < 0)
- lintwarn(_("or(%lf, %lf): negative values will give
strange results"), left, right);
+ lintwarn(_("or(%"NMOD"f, %"NMOD"f): negative values
will give strange results"), left, right);
if (double_to_int(left) != left || double_to_int(right) !=
right)
- lintwarn(_("or(%lf, %lf): fractional values will be
truncated"), left, right);
+ lintwarn(_("or(%"NMOD"f, %"NMOD"f): fractional values
will be truncated"), left, right);
}
free_temp(s1);
@@ -2988,9 +2988,9 @@ do_xor(NODE *tree)
right = force_number(s2);
if (do_lint) {
if (left < 0 || right < 0)
- lintwarn(_("xor(%lf, %lf): negative values will give
strange results"), left, right);
+ lintwarn(_("xor(%"NMOD"f, %"NMOD"f): negative values
will give strange results"), left, right);
if (double_to_int(left) != left || double_to_int(right) !=
right)
- lintwarn(_("xor(%lf, %lf): fractional values will be
truncated"), left, right);
+ lintwarn(_("xor(%"NMOD"f, %"NMOD"f): fractional values
will be truncated"), left, right);
}
free_temp(s1);
@@ -3009,7 +3009,7 @@ NODE *
do_compl(NODE *tree)
{
NODE *tmp;
- double d;
+ AWKNUM d;
uintmax_t uval;
tmp = tree_eval(tree->lnode);
@@ -3020,9 +3020,9 @@ do_compl(NODE *tree)
if (do_lint) {
if (d < 0)
- lintwarn(_("compl(%lf): negative value will give
strange results"), d);
+ lintwarn(_("compl(%"NMOD"f): negative value will give
strange results"), d);
if (double_to_int(d) != d)
- lintwarn(_("compl(%lf): fractional value will be
truncated"), d);
+ lintwarn(_("compl(%"NMOD"f): fractional value will be
truncated"), d);
}
uval = (uintmax_t) d;
diff --git a/configure.ac b/configure.ac
--- a/configure.ac
+++ b/configure.ac
@@ -198,6 +198,7 @@ gl_AC_TYPE_LONG_LONG
gl_AC_TYPE_UNSIGNED_LONG_LONG
gl_AC_TYPE_INTMAX_T
gl_AC_TYPE_UINTMAX_T
+AC_TYPE_LONG_DOUBLE_WIDER
AC_CHECK_TYPE(ssize_t, int)
AC_CHECK_SIZEOF(unsigned int)
AC_CHECK_SIZEOF(unsigned long)
diff --git a/floatcomp.c b/floatcomp.c
--- a/floatcomp.c
+++ b/floatcomp.c
@@ -79,6 +79,9 @@ Please port the following code to your w
AWKNUM
Floor(AWKNUM n)
{
+#ifdef HAVE_LONG_DOUBLE_WIDER
+ return floorl(n);
+#else
return floor(n
#if 0
#ifdef _CRAY
@@ -86,6 +89,7 @@ Floor(AWKNUM n)
#endif
#endif
);
+#endif
}
/* Ceil --- do ceil(), also for Cray */
@@ -93,6 +97,9 @@ Floor(AWKNUM n)
AWKNUM
Ceil(AWKNUM n)
{
+#ifdef HAVE_LONG_DOUBLE_WIDER
+ return ceill(n);
+#else
return ceil(n
#if 0
#ifdef _CRAY
@@ -100,6 +107,7 @@ Ceil(AWKNUM n)
#endif
#endif
);
+#endif
}
#ifdef HAVE_UINTMAX_T
diff --git a/profile.c b/profile.c
--- a/profile.c
+++ b/profile.c
@@ -456,7 +456,7 @@ tree_eval(register NODE *tree)
case Node_val:
if ((tree->flags & NUMBER) != 0)
- fprintf(prof_fp, "%g", tree->numbr);
+ fprintf(prof_fp, "%"NMOD"g", tree->numbr);
else {
if ((tree->flags & INTLSTR) != 0)
fprintf(prof_fp, "_");
diff --git a/test/Makefile.am b/test/Makefile.am
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -675,8 +675,6 @@ EXTRA_DIST = \
zeroflag.awk \
zeroflag.ok
-TESTS_WE_ARE_NOT_DOING_YET_FIXME_ONE_DAY = longdbl
-
# Get rid of core files when cleaning and generated .ok file
CLEANFILES = core core.* fmtspcl.ok
@@ -722,7 +720,7 @@ EXTRA_TESTS = regtest inftest
INET_TESTS = inetechu inetecht inetdayu inetdayt
-MACHINE_TESTS = double1 double2 fmtspcl intformat
+MACHINE_TESTS = double1 double2 fmtspcl intformat longdbl
LOCALE_CHARSET_TESTS = asort asorti fmttest fnarydel fnparydl lc_num1 mbfw1 \
mbprintf1 mbprintf2 rebt8b2 sort1 sprintfc whiny
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- gawk: use long double for AWKNUM when useful,
Jean-Marc Saffroy <=