gawk-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[gawk-diffs] [SCM] gawk branch, gawk-4.2-stable, updated. gawk-4.1.0-299


From: Arnold Robbins
Subject: [gawk-diffs] [SCM] gawk branch, gawk-4.2-stable, updated. gawk-4.1.0-2990-g8dba5f4
Date: Fri, 13 Jul 2018 06:56:50 -0400 (EDT)

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "gawk".

The branch, gawk-4.2-stable has been updated
       via  8dba5f4c900239d01897e2197ddd79bcf5d9b034 (commit)
       via  18ff7b4b066fdd606a66e90b1f3b489840e09560 (commit)
      from  120314daf8f9f2c6bb4a6d6a1900e726d63ef1de (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://git.sv.gnu.org/cgit/gawk.git/commit/?id=8dba5f4c900239d01897e2197ddd79bcf5d9b034

commit 8dba5f4c900239d01897e2197ddd79bcf5d9b034
Author: Arnold D. Robbins <address@hidden>
Date:   Fri Jul 13 13:56:10 2018 +0300

    Output +inf, +nan etc. also, so that output can be input. Doc, tests, fixed.

diff --git a/ChangeLog b/ChangeLog
index 947e46d..8e2c226 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,19 @@
+2018-07-13         Arnold D. Robbins     <address@hidden>
+
+       * builtin.c (format_nan_inf): New function to generate +nan, -nan,
+       +inf, -inf, so that gawk output for NaN and INF always has a sign.
+       Handles regular and MPFR.
+       (out_of_range): New function to check if a value is out of range,
+       both regular and MPFR.
+       (format_tree): Use them in out of range calculation.  Check for out
+       of range in floating point formats also. Allow new *undocumented*
+       'P' flag to not do out of range formantting. Used mainly for
+       the test program.
+       * awk.h (out_of_range, format_nan_inf): Declare functions.
+       * mpfr.c (mpg_format_val): Check for out of range and format the
+       the result appropriately if so.
+       * node.c (r_format_val): Ditto.
+
 2018-06-27         Arnold D. Robbins     <address@hidden>
 
        * config.guess, config.sub: Updated from GNULIB.
diff --git a/awk.h b/awk.h
index 31e661d..a6d8193 100644
--- a/awk.h
+++ b/awk.h
@@ -1678,6 +1678,8 @@ extern wint_t btowc_cache[];
 #define btowc_cache(x) btowc_cache[(x)&0xFF]
 extern void init_btowc_cache();
 #define is_valid_character(b)  (btowc_cache[(b)&0xFF] != WEOF)
+extern bool out_of_range(NODE *n);
+extern char *format_nan_inf(NODE *n, char format);
 /* re.c */
 extern Regexp *make_regexp(const char *s, size_t len, bool ignorecase, bool 
dfa, bool canfatal);
 extern int research(Regexp *rp, char *str, int start, size_t len, int flags);
diff --git a/builtin.c b/builtin.c
index c54be9b..44c484f 100644
--- a/builtin.c
+++ b/builtin.c
@@ -722,6 +722,8 @@ format_tree(
        int ii, jj;
        char *chp;
        size_t copy_count, char_count;
+       char *nan_inf_val;
+       bool magic_posix_flag;
 #ifdef HAVE_MPFR
        mpz_ptr zi;
        mpfr_ptr mf;
@@ -820,6 +822,7 @@ format_tree(
                signchar = '\0';
                zero_flag = false;
                quote_flag = false;
+               nan_inf_val = NULL;
 #ifdef HAVE_MPFR
                mf = NULL;
                zi = NULL;
@@ -827,6 +830,7 @@ format_tree(
                fmt_type = MP_NONE;
 
                lj = alt = big_flag = bigbig_flag = small_flag = false;
+               magic_posix_flag = false;
                fill = sp;
                cp = cend;
                chbuf = lchbuf;
@@ -1060,6 +1064,11 @@ check_pos:
                        }
                        small_flag = true;
                        goto retry;
+               case 'P':
+                       if (magic_posix_flag)
+                               break;
+                       magic_posix_flag = true;
+                       goto retry;
                case 'c':
                        need_format = false;
                        parse_next_arg();
@@ -1157,6 +1166,12 @@ out0:
                        need_format = false;
                        parse_next_arg();
                        (void) force_number(arg);
+
+                       /*
+                        * Check for Nan or Inf.
+                        */
+                       if (out_of_range(arg))
+                               goto out_of_range;
 #ifdef HAVE_MPFR
                        if (is_mpg_float(arg))
                                goto mpf0;
@@ -1164,15 +1179,7 @@ out0:
                                goto mpz0;
                        else
 #endif
-                       tmpval = arg->numbr;
-
-                       /*
-                        * Check for Nan or Inf.
-                        */
-                       if (isnan(tmpval) || isinf(tmpval))
-                               goto out_of_range;
-                       else
-                               tmpval = double_to_int(tmpval);
+                       tmpval = double_to_int(arg->numbr);
 
                        /*
                         * ``The result of converting a zero value with a
@@ -1286,6 +1293,9 @@ out0:
                        need_format = false;
                        parse_next_arg();
                        (void) force_number(arg);
+
+                       if (out_of_range(arg))
+                               goto out_of_range;
 #ifdef HAVE_MPFR
                        if (is_mpg_integer(arg)) {
 mpz0:
@@ -1476,12 +1486,27 @@ mpf1:
                        break;
 
      out_of_range:
-                       /* out of range - emergency use of %g format */
-                       if (do_lint)
-                               lintwarn(_("[s]printf: value %g is out of range 
for `%%%c' format"),
-                                                       (double) tmpval, cs1);
-                       cs1 = 'g';
-                       goto fmt1;
+                       /*
+                        * out of range - emergency use of %g format,
+                        * or format NaN and INF values.
+                        */
+                       nan_inf_val = format_nan_inf(arg, cs1);
+                       if (do_posix || magic_posix_flag || nan_inf_val == 
NULL) {
+                               if (do_lint && ! do_posix && ! magic_posix_flag)
+                                       lintwarn(_("[s]printf: value %g is out 
of range for `%%%c' format"),
+                                                               (double) 
tmpval, cs1);
+                               tmpval = arg->numbr;
+                               if (strchr("aAeEfFgG", cs1) == NULL)
+                                       cs1 = 'g';
+                               goto fmt1;
+                       } else {
+                               if (do_lint)
+                                       lintwarn(_("[s]printf: value %s is out 
of range for `%%%c' format"),
+                                                               nan_inf_val, 
cs1);
+                               bchunk(nan_inf_val, strlen(nan_inf_val));
+                               s0 = s1;
+                               break;
+                       }
 
                case 'F':
 #if ! defined(PRINTF_HAS_F_FORMAT) || PRINTF_HAS_F_FORMAT != 1
@@ -1498,6 +1523,7 @@ mpf1:
                case 'a':
                {
                        static bool warned = false;
+
                        if (do_lint && tolower(cs1) == 'a' && ! warned) {
                                warned = true;
                                lintwarn(_("%%%c format is POSIX standard but 
not portable to other awks"), cs1);
@@ -1521,6 +1547,9 @@ mpf1:
                                fmt_type = MP_FLOAT;
                        }
 #endif
+                       if (out_of_range(arg))
+                               goto out_of_range;
+
      fmt1:
                        if (! have_prec)
                                prec = DEFAULT_G_PRECISION;
@@ -4204,3 +4233,68 @@ int sanitize_exit_status(int status)
 
        return ret;
 }
+
+/* out_of_range --- return true if a value is out of range */
+
+bool
+out_of_range(NODE *n)
+{
+#ifdef HAVE_MPFR
+       if (is_mpg_integer(n))
+               return false;
+       else if (is_mpg_float(n))
+               return (! mpfr_number_p(n->mpg_numbr));
+       else
+#endif
+               return (isnan(n->numbr) || isinf(n->numbr));
+}
+
+/* format_nan_inf --- format NaN and INF values */
+
+char *
+format_nan_inf(NODE *n, char format)
+{
+       static char buf[100];
+
+#ifdef HAVE_MPFR
+       if (is_mpg_integer(n))
+               return NULL;
+       else if (is_mpg_float(n)) {
+               if (mpfr_nan_p(n->mpg_numbr)) {
+                       strcpy(buf, mpfr_sgn(n->mpg_numbr) < 0 ? "-nan" : 
"+nan");
+
+                       goto fmt;
+               } else if (mpfr_inf_p(n->mpg_numbr)) {
+                       strcpy(buf, mpfr_sgn(n->mpg_numbr) < 0 ? "-inf" : 
"+inf");
+
+                       goto fmt;
+               } else
+                       return NULL;
+       }
+       /* else
+               fallthrough */
+#endif
+       double val = n->numbr;
+
+       if (isnan(val)) {
+               strcpy(buf, signbit(val) != 0 ? "-nan" : "+nan");
+
+               // fall through to end
+       } else if (isinf(val)) {
+               strcpy(buf, val < 0 ? "-inf" : "+inf");
+
+               // fall through to end
+       } else
+               return NULL;
+
+#ifdef HAVE_MPFR
+fmt:
+#endif
+       if (isupper(format)) {
+               int i;
+
+               for (i = 0; buf[i] != '\0'; i++)
+                       buf[i] = toupper(buf[i]);
+       }
+       return buf;
+}
diff --git a/doc/ChangeLog b/doc/ChangeLog
index 33834a2..3f05800 100644
--- a/doc/ChangeLog
+++ b/doc/ChangeLog
@@ -1,3 +1,10 @@
+2018-07-10         Arnold D. Robbins     <address@hidden>
+
+       * gawktexi.in (Control Letters): Add a note about output of NaN and
+       INF values with an xref to POSIX Floating Point Problems.
+       (POSIX Floating Point Problems): Describe that gawk also outputs the
+       four special strings for NaN and INF values.
+
 2018-06-27         Arnold D. Robbins     <address@hidden>
 
        * texinfo.tex: Updated.
diff --git a/doc/gawk.info b/doc/gawk.info
index 29051f6..dc1aa07 100644
--- a/doc/gawk.info
+++ b/doc/gawk.info
@@ -6733,6 +6733,15 @@ width.  Here is a list of the format-control letters:
      versions of 'awk' may print invalid values or do something else
      entirely.  (d.c.)
 
+     NOTE: The IEEE 754 standard for floating-point arithmetic allows
+     for special values that represent "infinity" (positive and
+     negative) and values that are "not a number" (NaN).
+
+     Input and output of these values occurs as text strings.  This is
+     somewhat problematic for the 'awk' language, which predates the
+     IEEE standard.  Further details are provided in *note POSIX
+     Floating Point Problems::; please see there.
+
 
 File: gawk.info,  Node: Format Modifiers,  Next: Printf Examples,  Prev: 
Control Letters,  Up: Printf
 
@@ -23424,13 +23433,20 @@ and infinity values.  The solution implemented in 
'gawk' is as follows:
           $ echo nanny | gawk '{ print $1 + 0 }'
           -| 0
           $ echo +nan | gawk '{ print $1 + 0 }'
-          -| nan
+          -| +nan
           $ echo 0xDeadBeef | gawk '{ print $1 + 0 }'
           -| 0
 
      'gawk' ignores case in the four special values.  Thus, '+nan' and
      '+NaN' are the same.
 
+   Besides handling imput, 'gawk' also needs to print "correct" values
+on output when a value is either NaN or infinity.  Starting with version
+4.2.2, for such values 'gawk' prints one of the four strings just
+described: '+inf', '-inf', '+nan', or '-nan'.  Similarly, in POSIX mode,
+'gawk' prints the result of the system's C 'printf()' function using the
+'%g' format string for the value, whatever that may be.
+
    ---------- Footnotes ----------
 
    (1) You asked for it, you got it.
@@ -36170,456 +36186,456 @@ Node: OFMT289534
 Node: Printf290890
 Node: Basic Printf291675
 Node: Control Letters293249
-Node: Format Modifiers297928
-Node: Printf Examples303943
-Node: Redirection306429
-Node: Special FD313270
-Ref: Special FD-Footnote-1316438
-Node: Special Files316512
-Node: Other Inherited Files317129
-Node: Special Network318130
-Node: Special Caveats318990
-Node: Close Files And Pipes319939
-Ref: table-close-pipe-return-values326846
-Ref: Close Files And Pipes-Footnote-1327659
-Ref: Close Files And Pipes-Footnote-2327807
-Node: Nonfatal327959
-Node: Output Summary330297
-Node: Output Exercises331519
-Node: Expressions332198
-Node: Values333386
-Node: Constants334064
-Node: Scalar Constants334755
-Ref: Scalar Constants-Footnote-1335619
-Node: Nondecimal-numbers335869
-Node: Regexp Constants338870
-Node: Using Constant Regexps339396
-Node: Standard Regexp Constants340018
-Node: Strong Regexp Constants343206
-Node: Variables346164
-Node: Using Variables346821
-Node: Assignment Options348731
-Node: Conversion350604
-Node: Strings And Numbers351128
-Ref: Strings And Numbers-Footnote-1354191
-Node: Locale influences conversions354300
-Ref: table-locale-affects357058
-Node: All Operators357676
-Node: Arithmetic Ops358305
-Node: Concatenation360811
-Ref: Concatenation-Footnote-1363658
-Node: Assignment Ops363765
-Ref: table-assign-ops368756
-Node: Increment Ops370069
-Node: Truth Values and Conditions373529
-Node: Truth Values374603
-Node: Typing and Comparison375651
-Node: Variable Typing376471
-Ref: Variable Typing-Footnote-1382934
-Ref: Variable Typing-Footnote-2383006
-Node: Comparison Operators383083
-Ref: table-relational-ops383502
-Node: POSIX String Comparison386997
-Ref: POSIX String Comparison-Footnote-1388692
-Ref: POSIX String Comparison-Footnote-2388831
-Node: Boolean Ops388915
-Ref: Boolean Ops-Footnote-1393397
-Node: Conditional Exp393489
-Node: Function Calls395225
-Node: Precedence399102
-Node: Locales402761
-Node: Expressions Summary404393
-Node: Patterns and Actions406966
-Node: Pattern Overview408086
-Node: Regexp Patterns409763
-Node: Expression Patterns410305
-Node: Ranges414086
-Node: BEGIN/END417194
-Node: Using BEGIN/END417955
-Ref: Using BEGIN/END-Footnote-1420691
-Node: I/O And BEGIN/END420797
-Node: BEGINFILE/ENDFILE423111
-Node: Empty426024
-Node: Using Shell Variables426341
-Node: Action Overview428615
-Node: Statements430940
-Node: If Statement432788
-Node: While Statement434283
-Node: Do Statement436311
-Node: For Statement437459
-Node: Switch Statement440630
-Node: Break Statement443016
-Node: Continue Statement445108
-Node: Next Statement446935
-Node: Nextfile Statement449318
-Node: Exit Statement451970
-Node: Built-in Variables454373
-Node: User-modified455506
-Node: Auto-set463273
-Ref: Auto-set-Footnote-1479575
-Ref: Auto-set-Footnote-2479781
-Node: ARGC and ARGV479837
-Node: Pattern Action Summary484050
-Node: Arrays486480
-Node: Array Basics487809
-Node: Array Intro488653
-Ref: figure-array-elements490628
-Ref: Array Intro-Footnote-1493332
-Node: Reference to Elements493460
-Node: Assigning Elements495924
-Node: Array Example496415
-Node: Scanning an Array498174
-Node: Controlling Scanning501196
-Ref: Controlling Scanning-Footnote-1506595
-Node: Numeric Array Subscripts506911
-Node: Uninitialized Subscripts509095
-Node: Delete510714
-Ref: Delete-Footnote-1513466
-Node: Multidimensional513523
-Node: Multiscanning516618
-Node: Arrays of Arrays518209
-Node: Arrays Summary522976
-Node: Functions525069
-Node: Built-in526107
-Node: Calling Built-in527188
-Node: Numeric Functions529184
-Ref: Numeric Functions-Footnote-1533212
-Ref: Numeric Functions-Footnote-2533569
-Ref: Numeric Functions-Footnote-3533617
-Node: String Functions533889
-Ref: String Functions-Footnote-1557598
-Ref: String Functions-Footnote-2557726
-Ref: String Functions-Footnote-3557974
-Node: Gory Details558061
-Ref: table-sub-escapes559852
-Ref: table-sub-proposed561371
-Ref: table-posix-sub562734
-Ref: table-gensub-escapes564275
-Ref: Gory Details-Footnote-1565098
-Node: I/O Functions565252
-Ref: table-system-return-values571720
-Ref: I/O Functions-Footnote-1573700
-Ref: I/O Functions-Footnote-2573848
-Node: Time Functions573968
-Ref: Time Functions-Footnote-1584639
-Ref: Time Functions-Footnote-2584707
-Ref: Time Functions-Footnote-3584865
-Ref: Time Functions-Footnote-4584976
-Ref: Time Functions-Footnote-5585088
-Ref: Time Functions-Footnote-6585315
-Node: Bitwise Functions585581
-Ref: table-bitwise-ops586175
-Ref: Bitwise Functions-Footnote-1592238
-Ref: Bitwise Functions-Footnote-2592411
-Node: Type Functions592602
-Node: I18N Functions595353
-Node: User-defined597004
-Node: Definition Syntax597809
-Ref: Definition Syntax-Footnote-1603496
-Node: Function Example603567
-Ref: Function Example-Footnote-1606489
-Node: Function Caveats606511
-Node: Calling A Function607029
-Node: Variable Scope607987
-Node: Pass By Value/Reference610981
-Node: Return Statement614480
-Node: Dynamic Typing617459
-Node: Indirect Calls618389
-Ref: Indirect Calls-Footnote-1628641
-Node: Functions Summary628769
-Node: Library Functions631474
-Ref: Library Functions-Footnote-1635081
-Ref: Library Functions-Footnote-2635224
-Node: Library Names635395
-Ref: Library Names-Footnote-1638855
-Ref: Library Names-Footnote-2639078
-Node: General Functions639164
-Node: Strtonum Function640267
-Node: Assert Function643289
-Node: Round Function646615
-Node: Cliff Random Function648155
-Node: Ordinal Functions649171
-Ref: Ordinal Functions-Footnote-1652234
-Ref: Ordinal Functions-Footnote-2652486
-Node: Join Function652696
-Ref: Join Function-Footnote-1654466
-Node: Getlocaltime Function654666
-Node: Readfile Function658408
-Node: Shell Quoting660385
-Node: Data File Management661786
-Node: Filetrans Function662418
-Node: Rewind Function666514
-Node: File Checking668424
-Ref: File Checking-Footnote-1669758
-Node: Empty Files669959
-Node: Ignoring Assigns671938
-Node: Getopt Function673488
-Ref: Getopt Function-Footnote-1684957
-Node: Passwd Functions685157
-Ref: Passwd Functions-Footnote-1693996
-Node: Group Functions694084
-Ref: Group Functions-Footnote-1701982
-Node: Walking Arrays702189
-Node: Library Functions Summary705197
-Node: Library Exercises706603
-Node: Sample Programs707068
-Node: Running Examples707838
-Node: Clones708566
-Node: Cut Program709790
-Node: Egrep Program719719
-Ref: Egrep Program-Footnote-1727231
-Node: Id Program727341
-Node: Split Program731021
-Ref: Split Program-Footnote-1734479
-Node: Tee Program734608
-Node: Uniq Program737398
-Node: Wc Program744824
-Ref: Wc Program-Footnote-1749079
-Node: Miscellaneous Programs749173
-Node: Dupword Program750386
-Node: Alarm Program752416
-Node: Translate Program757271
-Ref: Translate Program-Footnote-1761836
-Node: Labels Program762106
-Ref: Labels Program-Footnote-1765457
-Node: Word Sorting765541
-Node: History Sorting769613
-Node: Extract Program771448
-Node: Simple Sed779502
-Node: Igawk Program782576
-Ref: Igawk Program-Footnote-1796907
-Ref: Igawk Program-Footnote-2797109
-Ref: Igawk Program-Footnote-3797231
-Node: Anagram Program797346
-Node: Signature Program800408
-Node: Programs Summary801655
-Node: Programs Exercises802869
-Ref: Programs Exercises-Footnote-1806998
-Node: Advanced Features807089
-Node: Nondecimal Data809079
-Node: Array Sorting810670
-Node: Controlling Array Traversal811370
-Ref: Controlling Array Traversal-Footnote-1819738
-Node: Array Sorting Functions819856
-Ref: Array Sorting Functions-Footnote-1824947
-Node: Two-way I/O825143
-Ref: Two-way I/O-Footnote-1831695
-Ref: Two-way I/O-Footnote-2831882
-Node: TCP/IP Networking831964
-Node: Profiling835082
-Ref: Profiling-Footnote-1843754
-Node: Advanced Features Summary844077
-Node: Internationalization845921
-Node: I18N and L10N847401
-Node: Explaining gettext848088
-Ref: Explaining gettext-Footnote-1853980
-Ref: Explaining gettext-Footnote-2854165
-Node: Programmer i18n854330
-Ref: Programmer i18n-Footnote-1859279
-Node: Translator i18n859328
-Node: String Extraction860122
-Ref: String Extraction-Footnote-1861254
-Node: Printf Ordering861340
-Ref: Printf Ordering-Footnote-1864126
-Node: I18N Portability864190
-Ref: I18N Portability-Footnote-1866646
-Node: I18N Example866709
-Ref: I18N Example-Footnote-1869515
-Node: Gawk I18N869588
-Node: I18N Summary870233
-Node: Debugger871574
-Node: Debugging872597
-Node: Debugging Concepts873038
-Node: Debugging Terms874847
-Node: Awk Debugging877422
-Node: Sample Debugging Session878328
-Node: Debugger Invocation878862
-Node: Finding The Bug880248
-Node: List of Debugger Commands886726
-Node: Breakpoint Control888059
-Node: Debugger Execution Control891753
-Node: Viewing And Changing Data895115
-Node: Execution Stack898489
-Node: Debugger Info900126
-Node: Miscellaneous Debugger Commands904197
-Node: Readline Support909259
-Node: Limitations910155
-Node: Debugging Summary912264
-Node: Arbitrary Precision Arithmetic913543
-Node: Computer Arithmetic915028
-Ref: table-numeric-ranges918794
-Ref: table-floating-point-ranges919287
-Ref: Computer Arithmetic-Footnote-1919945
-Node: Math Definitions920002
-Ref: table-ieee-formats923318
-Ref: Math Definitions-Footnote-1923921
-Node: MPFR features924026
-Node: FP Math Caution925744
-Ref: FP Math Caution-Footnote-1926816
-Node: Inexactness of computations927185
-Node: Inexact representation928145
-Node: Comparing FP Values929505
-Node: Errors accumulate930587
-Node: Getting Accuracy932020
-Node: Try To Round934730
-Node: Setting precision935629
-Ref: table-predefined-precision-strings936326
-Node: Setting the rounding mode938156
-Ref: table-gawk-rounding-modes938530
-Ref: Setting the rounding mode-Footnote-1942461
-Node: Arbitrary Precision Integers942640
-Ref: Arbitrary Precision Integers-Footnote-1945815
-Node: Checking for MPFR945964
-Node: POSIX Floating Point Problems947438
-Ref: POSIX Floating Point Problems-Footnote-1951309
-Node: Floating point summary951347
-Node: Dynamic Extensions953537
-Node: Extension Intro955090
-Node: Plugin License956356
-Node: Extension Mechanism Outline957153
-Ref: figure-load-extension957592
-Ref: figure-register-new-function959157
-Ref: figure-call-new-function960249
-Node: Extension API Description962311
-Node: Extension API Functions Introduction963953
-Node: General Data Types969493
-Ref: General Data Types-Footnote-1977854
-Node: Memory Allocation Functions978153
-Ref: Memory Allocation Functions-Footnote-1982363
-Node: Constructor Functions982462
-Node: Registration Functions986048
-Node: Extension Functions986733
-Node: Exit Callback Functions991948
-Node: Extension Version String993198
-Node: Input Parsers993861
-Node: Output Wrappers1006582
-Node: Two-way processors1011094
-Node: Printing Messages1013359
-Ref: Printing Messages-Footnote-11014530
-Node: Updating ERRNO1014683
-Node: Requesting Values1015422
-Ref: table-value-types-returned1016159
-Node: Accessing Parameters1017095
-Node: Symbol Table Access1018330
-Node: Symbol table by name1018842
-Node: Symbol table by cookie1020631
-Ref: Symbol table by cookie-Footnote-11024816
-Node: Cached values1024880
-Ref: Cached values-Footnote-11028416
-Node: Array Manipulation1028569
-Ref: Array Manipulation-Footnote-11029660
-Node: Array Data Types1029697
-Ref: Array Data Types-Footnote-11032355
-Node: Array Functions1032447
-Node: Flattening Arrays1036945
-Node: Creating Arrays1043921
-Node: Redirection API1048688
-Node: Extension API Variables1051521
-Node: Extension Versioning1052232
-Ref: gawk-api-version1052661
-Node: Extension GMP/MPFR Versioning1054392
-Node: Extension API Informational Variables1056020
-Node: Extension API Boilerplate1057093
-Node: Changes from API V11061067
-Node: Finding Extensions1062639
-Node: Extension Example1063198
-Node: Internal File Description1063996
-Node: Internal File Ops1068076
-Ref: Internal File Ops-Footnote-11079426
-Node: Using Internal File Ops1079566
-Ref: Using Internal File Ops-Footnote-11081949
-Node: Extension Samples1082223
-Node: Extension Sample File Functions1083752
-Node: Extension Sample Fnmatch1091401
-Node: Extension Sample Fork1092888
-Node: Extension Sample Inplace1094106
-Node: Extension Sample Ord1097323
-Node: Extension Sample Readdir1098159
-Ref: table-readdir-file-types1099048
-Node: Extension Sample Revout1099853
-Node: Extension Sample Rev2way1100442
-Node: Extension Sample Read write array1101182
-Node: Extension Sample Readfile1103124
-Node: Extension Sample Time1104219
-Node: Extension Sample API Tests1105567
-Node: gawkextlib1106059
-Node: Extension summary1108977
-Node: Extension Exercises1112679
-Node: Language History1114177
-Node: V7/SVR3.11115833
-Node: SVR41117985
-Node: POSIX1119419
-Node: BTL1120799
-Node: POSIX/GNU1121528
-Node: Feature History1127306
-Node: Common Extensions1143165
-Node: Ranges and Locales1144448
-Ref: Ranges and Locales-Footnote-11149064
-Ref: Ranges and Locales-Footnote-21149091
-Ref: Ranges and Locales-Footnote-31149326
-Node: Contributors1149547
-Node: History summary1155492
-Node: Installation1156872
-Node: Gawk Distribution1157816
-Node: Getting1158300
-Node: Extracting1159263
-Node: Distribution contents1160901
-Node: Unix Installation1167381
-Node: Quick Installation1168063
-Node: Shell Startup Files1170477
-Node: Additional Configuration Options1171566
-Node: Configuration Philosophy1173859
-Node: Non-Unix Installation1176228
-Node: PC Installation1176688
-Node: PC Binary Installation1177526
-Node: PC Compiling1177961
-Node: PC Using1179078
-Node: Cygwin1182293
-Node: MSYS1183392
-Node: VMS Installation1183893
-Node: VMS Compilation1184684
-Ref: VMS Compilation-Footnote-11185913
-Node: VMS Dynamic Extensions1185971
-Node: VMS Installation Details1187656
-Node: VMS Running1189909
-Node: VMS GNV1194188
-Node: VMS Old Gawk1194923
-Node: Bugs1195394
-Node: Bug address1196057
-Node: Usenet1198849
-Node: Maintainers1199626
-Node: Other Versions1200887
-Node: Installation summary1207649
-Node: Notes1208851
-Node: Compatibility Mode1209716
-Node: Additions1210498
-Node: Accessing The Source1211423
-Node: Adding Code1212860
-Node: New Ports1219079
-Node: Derived Files1223567
-Ref: Derived Files-Footnote-11229213
-Ref: Derived Files-Footnote-21229248
-Ref: Derived Files-Footnote-31229846
-Node: Future Extensions1229960
-Node: Implementation Limitations1230618
-Node: Extension Design1231801
-Node: Old Extension Problems1232955
-Ref: Old Extension Problems-Footnote-11234473
-Node: Extension New Mechanism Goals1234530
-Ref: Extension New Mechanism Goals-Footnote-11237894
-Node: Extension Other Design Decisions1238083
-Node: Extension Future Growth1240196
-Node: Old Extension Mechanism1241032
-Node: Notes summary1242795
-Node: Basic Concepts1243977
-Node: Basic High Level1244658
-Ref: figure-general-flow1244940
-Ref: figure-process-flow1245625
-Ref: Basic High Level-Footnote-11248926
-Node: Basic Data Typing1249111
-Node: Glossary1252439
-Node: Copying1284277
-Node: GNU Free Documentation License1321820
-Node: Index1346940
+Node: Format Modifiers298376
+Node: Printf Examples304391
+Node: Redirection306877
+Node: Special FD313718
+Ref: Special FD-Footnote-1316886
+Node: Special Files316960
+Node: Other Inherited Files317577
+Node: Special Network318578
+Node: Special Caveats319438
+Node: Close Files And Pipes320387
+Ref: table-close-pipe-return-values327294
+Ref: Close Files And Pipes-Footnote-1328107
+Ref: Close Files And Pipes-Footnote-2328255
+Node: Nonfatal328407
+Node: Output Summary330745
+Node: Output Exercises331967
+Node: Expressions332646
+Node: Values333834
+Node: Constants334512
+Node: Scalar Constants335203
+Ref: Scalar Constants-Footnote-1336067
+Node: Nondecimal-numbers336317
+Node: Regexp Constants339318
+Node: Using Constant Regexps339844
+Node: Standard Regexp Constants340466
+Node: Strong Regexp Constants343654
+Node: Variables346612
+Node: Using Variables347269
+Node: Assignment Options349179
+Node: Conversion351052
+Node: Strings And Numbers351576
+Ref: Strings And Numbers-Footnote-1354639
+Node: Locale influences conversions354748
+Ref: table-locale-affects357506
+Node: All Operators358124
+Node: Arithmetic Ops358753
+Node: Concatenation361259
+Ref: Concatenation-Footnote-1364106
+Node: Assignment Ops364213
+Ref: table-assign-ops369204
+Node: Increment Ops370517
+Node: Truth Values and Conditions373977
+Node: Truth Values375051
+Node: Typing and Comparison376099
+Node: Variable Typing376919
+Ref: Variable Typing-Footnote-1383382
+Ref: Variable Typing-Footnote-2383454
+Node: Comparison Operators383531
+Ref: table-relational-ops383950
+Node: POSIX String Comparison387445
+Ref: POSIX String Comparison-Footnote-1389140
+Ref: POSIX String Comparison-Footnote-2389279
+Node: Boolean Ops389363
+Ref: Boolean Ops-Footnote-1393845
+Node: Conditional Exp393937
+Node: Function Calls395673
+Node: Precedence399550
+Node: Locales403209
+Node: Expressions Summary404841
+Node: Patterns and Actions407414
+Node: Pattern Overview408534
+Node: Regexp Patterns410211
+Node: Expression Patterns410753
+Node: Ranges414534
+Node: BEGIN/END417642
+Node: Using BEGIN/END418403
+Ref: Using BEGIN/END-Footnote-1421139
+Node: I/O And BEGIN/END421245
+Node: BEGINFILE/ENDFILE423559
+Node: Empty426472
+Node: Using Shell Variables426789
+Node: Action Overview429063
+Node: Statements431388
+Node: If Statement433236
+Node: While Statement434731
+Node: Do Statement436759
+Node: For Statement437907
+Node: Switch Statement441078
+Node: Break Statement443464
+Node: Continue Statement445556
+Node: Next Statement447383
+Node: Nextfile Statement449766
+Node: Exit Statement452418
+Node: Built-in Variables454821
+Node: User-modified455954
+Node: Auto-set463721
+Ref: Auto-set-Footnote-1480023
+Ref: Auto-set-Footnote-2480229
+Node: ARGC and ARGV480285
+Node: Pattern Action Summary484498
+Node: Arrays486928
+Node: Array Basics488257
+Node: Array Intro489101
+Ref: figure-array-elements491076
+Ref: Array Intro-Footnote-1493780
+Node: Reference to Elements493908
+Node: Assigning Elements496372
+Node: Array Example496863
+Node: Scanning an Array498622
+Node: Controlling Scanning501644
+Ref: Controlling Scanning-Footnote-1507043
+Node: Numeric Array Subscripts507359
+Node: Uninitialized Subscripts509543
+Node: Delete511162
+Ref: Delete-Footnote-1513914
+Node: Multidimensional513971
+Node: Multiscanning517066
+Node: Arrays of Arrays518657
+Node: Arrays Summary523424
+Node: Functions525517
+Node: Built-in526555
+Node: Calling Built-in527636
+Node: Numeric Functions529632
+Ref: Numeric Functions-Footnote-1533660
+Ref: Numeric Functions-Footnote-2534017
+Ref: Numeric Functions-Footnote-3534065
+Node: String Functions534337
+Ref: String Functions-Footnote-1558046
+Ref: String Functions-Footnote-2558174
+Ref: String Functions-Footnote-3558422
+Node: Gory Details558509
+Ref: table-sub-escapes560300
+Ref: table-sub-proposed561819
+Ref: table-posix-sub563182
+Ref: table-gensub-escapes564723
+Ref: Gory Details-Footnote-1565546
+Node: I/O Functions565700
+Ref: table-system-return-values572168
+Ref: I/O Functions-Footnote-1574148
+Ref: I/O Functions-Footnote-2574296
+Node: Time Functions574416
+Ref: Time Functions-Footnote-1585087
+Ref: Time Functions-Footnote-2585155
+Ref: Time Functions-Footnote-3585313
+Ref: Time Functions-Footnote-4585424
+Ref: Time Functions-Footnote-5585536
+Ref: Time Functions-Footnote-6585763
+Node: Bitwise Functions586029
+Ref: table-bitwise-ops586623
+Ref: Bitwise Functions-Footnote-1592686
+Ref: Bitwise Functions-Footnote-2592859
+Node: Type Functions593050
+Node: I18N Functions595801
+Node: User-defined597452
+Node: Definition Syntax598257
+Ref: Definition Syntax-Footnote-1603944
+Node: Function Example604015
+Ref: Function Example-Footnote-1606937
+Node: Function Caveats606959
+Node: Calling A Function607477
+Node: Variable Scope608435
+Node: Pass By Value/Reference611429
+Node: Return Statement614928
+Node: Dynamic Typing617907
+Node: Indirect Calls618837
+Ref: Indirect Calls-Footnote-1629089
+Node: Functions Summary629217
+Node: Library Functions631922
+Ref: Library Functions-Footnote-1635529
+Ref: Library Functions-Footnote-2635672
+Node: Library Names635843
+Ref: Library Names-Footnote-1639303
+Ref: Library Names-Footnote-2639526
+Node: General Functions639612
+Node: Strtonum Function640715
+Node: Assert Function643737
+Node: Round Function647063
+Node: Cliff Random Function648603
+Node: Ordinal Functions649619
+Ref: Ordinal Functions-Footnote-1652682
+Ref: Ordinal Functions-Footnote-2652934
+Node: Join Function653144
+Ref: Join Function-Footnote-1654914
+Node: Getlocaltime Function655114
+Node: Readfile Function658856
+Node: Shell Quoting660833
+Node: Data File Management662234
+Node: Filetrans Function662866
+Node: Rewind Function666962
+Node: File Checking668872
+Ref: File Checking-Footnote-1670206
+Node: Empty Files670407
+Node: Ignoring Assigns672386
+Node: Getopt Function673936
+Ref: Getopt Function-Footnote-1685405
+Node: Passwd Functions685605
+Ref: Passwd Functions-Footnote-1694444
+Node: Group Functions694532
+Ref: Group Functions-Footnote-1702430
+Node: Walking Arrays702637
+Node: Library Functions Summary705645
+Node: Library Exercises707051
+Node: Sample Programs707516
+Node: Running Examples708286
+Node: Clones709014
+Node: Cut Program710238
+Node: Egrep Program720167
+Ref: Egrep Program-Footnote-1727679
+Node: Id Program727789
+Node: Split Program731469
+Ref: Split Program-Footnote-1734927
+Node: Tee Program735056
+Node: Uniq Program737846
+Node: Wc Program745272
+Ref: Wc Program-Footnote-1749527
+Node: Miscellaneous Programs749621
+Node: Dupword Program750834
+Node: Alarm Program752864
+Node: Translate Program757719
+Ref: Translate Program-Footnote-1762284
+Node: Labels Program762554
+Ref: Labels Program-Footnote-1765905
+Node: Word Sorting765989
+Node: History Sorting770061
+Node: Extract Program771896
+Node: Simple Sed779950
+Node: Igawk Program783024
+Ref: Igawk Program-Footnote-1797355
+Ref: Igawk Program-Footnote-2797557
+Ref: Igawk Program-Footnote-3797679
+Node: Anagram Program797794
+Node: Signature Program800856
+Node: Programs Summary802103
+Node: Programs Exercises803317
+Ref: Programs Exercises-Footnote-1807446
+Node: Advanced Features807537
+Node: Nondecimal Data809527
+Node: Array Sorting811118
+Node: Controlling Array Traversal811818
+Ref: Controlling Array Traversal-Footnote-1820186
+Node: Array Sorting Functions820304
+Ref: Array Sorting Functions-Footnote-1825395
+Node: Two-way I/O825591
+Ref: Two-way I/O-Footnote-1832143
+Ref: Two-way I/O-Footnote-2832330
+Node: TCP/IP Networking832412
+Node: Profiling835530
+Ref: Profiling-Footnote-1844202
+Node: Advanced Features Summary844525
+Node: Internationalization846369
+Node: I18N and L10N847849
+Node: Explaining gettext848536
+Ref: Explaining gettext-Footnote-1854428
+Ref: Explaining gettext-Footnote-2854613
+Node: Programmer i18n854778
+Ref: Programmer i18n-Footnote-1859727
+Node: Translator i18n859776
+Node: String Extraction860570
+Ref: String Extraction-Footnote-1861702
+Node: Printf Ordering861788
+Ref: Printf Ordering-Footnote-1864574
+Node: I18N Portability864638
+Ref: I18N Portability-Footnote-1867094
+Node: I18N Example867157
+Ref: I18N Example-Footnote-1869963
+Node: Gawk I18N870036
+Node: I18N Summary870681
+Node: Debugger872022
+Node: Debugging873045
+Node: Debugging Concepts873486
+Node: Debugging Terms875295
+Node: Awk Debugging877870
+Node: Sample Debugging Session878776
+Node: Debugger Invocation879310
+Node: Finding The Bug880696
+Node: List of Debugger Commands887174
+Node: Breakpoint Control888507
+Node: Debugger Execution Control892201
+Node: Viewing And Changing Data895563
+Node: Execution Stack898937
+Node: Debugger Info900574
+Node: Miscellaneous Debugger Commands904645
+Node: Readline Support909707
+Node: Limitations910603
+Node: Debugging Summary912712
+Node: Arbitrary Precision Arithmetic913991
+Node: Computer Arithmetic915476
+Ref: table-numeric-ranges919242
+Ref: table-floating-point-ranges919735
+Ref: Computer Arithmetic-Footnote-1920393
+Node: Math Definitions920450
+Ref: table-ieee-formats923766
+Ref: Math Definitions-Footnote-1924369
+Node: MPFR features924474
+Node: FP Math Caution926192
+Ref: FP Math Caution-Footnote-1927264
+Node: Inexactness of computations927633
+Node: Inexact representation928593
+Node: Comparing FP Values929953
+Node: Errors accumulate931035
+Node: Getting Accuracy932468
+Node: Try To Round935178
+Node: Setting precision936077
+Ref: table-predefined-precision-strings936774
+Node: Setting the rounding mode938604
+Ref: table-gawk-rounding-modes938978
+Ref: Setting the rounding mode-Footnote-1942909
+Node: Arbitrary Precision Integers943088
+Ref: Arbitrary Precision Integers-Footnote-1946263
+Node: Checking for MPFR946412
+Node: POSIX Floating Point Problems947886
+Ref: POSIX Floating Point Problems-Footnote-1952171
+Node: Floating point summary952209
+Node: Dynamic Extensions954399
+Node: Extension Intro955952
+Node: Plugin License957218
+Node: Extension Mechanism Outline958015
+Ref: figure-load-extension958454
+Ref: figure-register-new-function960019
+Ref: figure-call-new-function961111
+Node: Extension API Description963173
+Node: Extension API Functions Introduction964815
+Node: General Data Types970355
+Ref: General Data Types-Footnote-1978716
+Node: Memory Allocation Functions979015
+Ref: Memory Allocation Functions-Footnote-1983225
+Node: Constructor Functions983324
+Node: Registration Functions986910
+Node: Extension Functions987595
+Node: Exit Callback Functions992810
+Node: Extension Version String994060
+Node: Input Parsers994723
+Node: Output Wrappers1007444
+Node: Two-way processors1011956
+Node: Printing Messages1014221
+Ref: Printing Messages-Footnote-11015392
+Node: Updating ERRNO1015545
+Node: Requesting Values1016284
+Ref: table-value-types-returned1017021
+Node: Accessing Parameters1017957
+Node: Symbol Table Access1019192
+Node: Symbol table by name1019704
+Node: Symbol table by cookie1021493
+Ref: Symbol table by cookie-Footnote-11025678
+Node: Cached values1025742
+Ref: Cached values-Footnote-11029278
+Node: Array Manipulation1029431
+Ref: Array Manipulation-Footnote-11030522
+Node: Array Data Types1030559
+Ref: Array Data Types-Footnote-11033217
+Node: Array Functions1033309
+Node: Flattening Arrays1037807
+Node: Creating Arrays1044783
+Node: Redirection API1049550
+Node: Extension API Variables1052383
+Node: Extension Versioning1053094
+Ref: gawk-api-version1053523
+Node: Extension GMP/MPFR Versioning1055254
+Node: Extension API Informational Variables1056882
+Node: Extension API Boilerplate1057955
+Node: Changes from API V11061929
+Node: Finding Extensions1063501
+Node: Extension Example1064060
+Node: Internal File Description1064858
+Node: Internal File Ops1068938
+Ref: Internal File Ops-Footnote-11080288
+Node: Using Internal File Ops1080428
+Ref: Using Internal File Ops-Footnote-11082811
+Node: Extension Samples1083085
+Node: Extension Sample File Functions1084614
+Node: Extension Sample Fnmatch1092263
+Node: Extension Sample Fork1093750
+Node: Extension Sample Inplace1094968
+Node: Extension Sample Ord1098185
+Node: Extension Sample Readdir1099021
+Ref: table-readdir-file-types1099910
+Node: Extension Sample Revout1100715
+Node: Extension Sample Rev2way1101304
+Node: Extension Sample Read write array1102044
+Node: Extension Sample Readfile1103986
+Node: Extension Sample Time1105081
+Node: Extension Sample API Tests1106429
+Node: gawkextlib1106921
+Node: Extension summary1109839
+Node: Extension Exercises1113541
+Node: Language History1115039
+Node: V7/SVR3.11116695
+Node: SVR41118847
+Node: POSIX1120281
+Node: BTL1121661
+Node: POSIX/GNU1122390
+Node: Feature History1128168
+Node: Common Extensions1144027
+Node: Ranges and Locales1145310
+Ref: Ranges and Locales-Footnote-11149926
+Ref: Ranges and Locales-Footnote-21149953
+Ref: Ranges and Locales-Footnote-31150188
+Node: Contributors1150409
+Node: History summary1156354
+Node: Installation1157734
+Node: Gawk Distribution1158678
+Node: Getting1159162
+Node: Extracting1160125
+Node: Distribution contents1161763
+Node: Unix Installation1168243
+Node: Quick Installation1168925
+Node: Shell Startup Files1171339
+Node: Additional Configuration Options1172428
+Node: Configuration Philosophy1174721
+Node: Non-Unix Installation1177090
+Node: PC Installation1177550
+Node: PC Binary Installation1178388
+Node: PC Compiling1178823
+Node: PC Using1179940
+Node: Cygwin1183155
+Node: MSYS1184254
+Node: VMS Installation1184755
+Node: VMS Compilation1185546
+Ref: VMS Compilation-Footnote-11186775
+Node: VMS Dynamic Extensions1186833
+Node: VMS Installation Details1188518
+Node: VMS Running1190771
+Node: VMS GNV1195050
+Node: VMS Old Gawk1195785
+Node: Bugs1196256
+Node: Bug address1196919
+Node: Usenet1199711
+Node: Maintainers1200488
+Node: Other Versions1201749
+Node: Installation summary1208511
+Node: Notes1209713
+Node: Compatibility Mode1210578
+Node: Additions1211360
+Node: Accessing The Source1212285
+Node: Adding Code1213722
+Node: New Ports1219941
+Node: Derived Files1224429
+Ref: Derived Files-Footnote-11230075
+Ref: Derived Files-Footnote-21230110
+Ref: Derived Files-Footnote-31230708
+Node: Future Extensions1230822
+Node: Implementation Limitations1231480
+Node: Extension Design1232663
+Node: Old Extension Problems1233817
+Ref: Old Extension Problems-Footnote-11235335
+Node: Extension New Mechanism Goals1235392
+Ref: Extension New Mechanism Goals-Footnote-11238756
+Node: Extension Other Design Decisions1238945
+Node: Extension Future Growth1241058
+Node: Old Extension Mechanism1241894
+Node: Notes summary1243657
+Node: Basic Concepts1244839
+Node: Basic High Level1245520
+Ref: figure-general-flow1245802
+Ref: figure-process-flow1246487
+Ref: Basic High Level-Footnote-11249788
+Node: Basic Data Typing1249973
+Node: Glossary1253301
+Node: Copying1285139
+Node: GNU Free Documentation License1322682
+Node: Index1347802
 
 End Tag Table
diff --git a/doc/gawk.texi b/doc/gawk.texi
index 7da5048..3b7c2bf 100644
--- a/doc/gawk.texi
+++ b/doc/gawk.texi
@@ -4988,6 +4988,12 @@ function names added by @command{gawk} after the code 
was written.
 Standard @command{awk} built-in functions, such as @code{sin()} or
 @code{substr()} are @emph{not} shadowed in this way.
 
+You can use a @samp{P} modifier for the @code{printf()} floating-point
+format control letters to use the underlying C library's result for
+NaN and Infinity values, instead of the special values @command{gawk}
+usually produces, as described in @ref{POSIX Floating Point Problems}.
+This is mainly useful for the included unit tests.
+
 @end ignore
 
 @node Invoking Summary
@@ -9712,6 +9718,17 @@ values or do something else entirely.
 @value{DARKCORNER}
 @end quotation
 
address@hidden NOTE
+The IEEE 754 standard for floating-point arithmetic allows for special
+values that represent ``infinity'' (positive and negative) and values
+that are ``not a number'' (NaN).
+
+Input and output of these values occurs as text strings. This is
+somewhat problematic for the @command{awk} language, which predates
+the IEEE standard.  Further details are provided in
address@hidden Floating Point Problems}; please see there.
address@hidden quotation
+
 @node Format Modifiers
 @subsection Modifiers for @code{printf} Formats
 
@@ -32627,7 +32644,7 @@ which is @emph{not} recommended). For example:
 $ @kbd{echo nanny | gawk '@{ print $1 + 0 @}'}
 @print{} 0
 $ @kbd{echo +nan | gawk '@{ print $1 + 0 @}'}
address@hidden nan
address@hidden +nan
 $ @kbd{echo 0xDeadBeef | gawk '@{ print $1 + 0 @}'}
 @print{} 0
 @end example
@@ -32636,6 +32653,14 @@ $ @kbd{echo 0xDeadBeef | gawk '@{ print $1 + 0 @}'}
 Thus, @samp{+nan} and @samp{+NaN} are the same.
 @end itemize
 
+Besides handling imput, @command{gawk} also needs to print ``correct'' values 
on
+output when a value is either NaN or infinity. Starting with version 4.2.2,
+for such values @command{gawk} prints one of the four strings
+just described: @samp{+inf}, @samp{-inf}, @samp{+nan}, or @samp{-nan}.
+Similarly, in POSIX mode, @command{gawk} prints the result of
+the system's C @code{printf()} function using the @code{%g} format string
+for the value, whatever that may be.
+
 @node Floating point summary
 @section Summary
 
diff --git a/doc/gawktexi.in b/doc/gawktexi.in
index a9a670d..8c4cb89 100644
--- a/doc/gawktexi.in
+++ b/doc/gawktexi.in
@@ -4898,6 +4898,12 @@ function names added by @command{gawk} after the code 
was written.
 Standard @command{awk} built-in functions, such as @code{sin()} or
 @code{substr()} are @emph{not} shadowed in this way.
 
+You can use a @samp{P} modifier for the @code{printf()} floating-point
+format control letters to use the underlying C library's result for
+NaN and Infinity values, instead of the special values @command{gawk}
+usually produces, as described in @ref{POSIX Floating Point Problems}.
+This is mainly useful for the included unit tests.
+
 @end ignore
 
 @node Invoking Summary
@@ -9311,6 +9317,17 @@ values or do something else entirely.
 @value{DARKCORNER}
 @end quotation
 
address@hidden NOTE
+The IEEE 754 standard for floating-point arithmetic allows for special
+values that represent ``infinity'' (positive and negative) and values
+that are ``not a number'' (NaN).
+
+Input and output of these values occurs as text strings. This is
+somewhat problematic for the @command{awk} language, which predates
+the IEEE standard.  Further details are provided in
address@hidden Floating Point Problems}; please see there.
address@hidden quotation
+
 @node Format Modifiers
 @subsection Modifiers for @code{printf} Formats
 
@@ -31601,7 +31618,7 @@ which is @emph{not} recommended). For example:
 $ @kbd{echo nanny | gawk '@{ print $1 + 0 @}'}
 @print{} 0
 $ @kbd{echo +nan | gawk '@{ print $1 + 0 @}'}
address@hidden nan
address@hidden +nan
 $ @kbd{echo 0xDeadBeef | gawk '@{ print $1 + 0 @}'}
 @print{} 0
 @end example
@@ -31610,6 +31627,14 @@ $ @kbd{echo 0xDeadBeef | gawk '@{ print $1 + 0 @}'}
 Thus, @samp{+nan} and @samp{+NaN} are the same.
 @end itemize
 
+Besides handling imput, @command{gawk} also needs to print ``correct'' values 
on
+output when a value is either NaN or infinity. Starting with version 4.2.2,
+for such values @command{gawk} prints one of the four strings
+just described: @samp{+inf}, @samp{-inf}, @samp{+nan}, or @samp{-nan}.
+Similarly, in POSIX mode, @command{gawk} prints the result of
+the system's C @code{printf()} function using the @code{%g} format string
+for the value, whatever that may be.
+
 @node Floating point summary
 @section Summary
 
diff --git a/mpfr.c b/mpfr.c
index 0c962c6..b6e9c16 100644
--- a/mpfr.c
+++ b/mpfr.c
@@ -357,6 +357,11 @@ mpg_format_val(const char *format, int index, NODE *s)
        NODE *dummy[2], *r;
        unsigned int oflags;
 
+       if (out_of_range(s)) {
+               const char *result = format_nan_inf(s, 'g');
+               return make_string(result, strlen(result));
+       }
+
        /* create dummy node for a sole use of format_tree */
        dummy[1] = s;
        oflags = s->flags;
diff --git a/node.c b/node.c
index 984cec8..54ea662 100644
--- a/node.c
+++ b/node.c
@@ -219,10 +219,13 @@ r_format_val(const char *format, int index, NODE *s)
         * < and > so that things work correctly on systems with 64 bit 
integers.
         */
 
-       /* not an integral value, or out of range */
-       if ((val = double_to_int(s->numbr)) != s->numbr
+       if (out_of_range(s)) {
+               const char *result = format_nan_inf(s, 'g');
+               return make_string(result, strlen(result));
+       } else if ((val = double_to_int(s->numbr)) != s->numbr
                        || val <= LONG_MIN || val >= LONG_MAX
        ) {
+               /* not an integral value, or out of integer range */
                /*
                 * Once upon a time, we just blindly did this:
                 *      sprintf(sp, format, s->numbr);
diff --git a/test/ChangeLog b/test/ChangeLog
index b8816a5..2d85c9a 100644
--- a/test/ChangeLog
+++ b/test/ChangeLog
@@ -1,3 +1,11 @@
+2018-07-13         Arnold D. Robbins     <address@hidden>
+
+       * fmtspcl.awk, fmtspcl.tok, numrange.ok: Revised after code changes
+       in gawk.
+       * fix-fmtscl.awk: New file.
+       * Makefile.am (fmtspcl.tok): Use fix-fmtscpl.awk instead of
+       inline program.
+
 2018-07-12         Arnold D. Robbins     <address@hidden>
 
        * fmtspcl.awk: Improve the formatting, add testing of uppercase
diff --git a/test/Makefile.am b/test/Makefile.am
index e4cca53..4ab9640 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -278,6 +278,7 @@ EXTRA_DIST = \
        fieldwdth.ok \
        filefuncs.awk \
        filefuncs.ok \
+       fix-fmtspcl.awk \
        fldchg.awk \
        fldchg.in \
        fldchg.ok \
@@ -1687,8 +1688,8 @@ nors::
        @echo A B C D E | tr -d '\12\15' | $(AWK) '{ print $$NF }' - 
"$(srcdir)"/nors.in > _$@ || echo EXIT CODE: $$? >> _$@
        @-$(CMP) "$(srcdir)"/address@hidden _$@ && rm -f _$@
 
-fmtspcl.ok: fmtspcl.tok Makefile
-       @$(AWK) -v "sd=$(srcdir)" 'BEGIN {pnan = sprintf("%g",sqrt(-1)); nnan = 
sprintf("%g",-sqrt(-1)); pinf = sprintf("%g",-log(0)); ninf = 
sprintf("%g",log(0))} {sub(/positive_nan/,pnan); sub(/negative_nan/,nnan); 
sub(/positive_infinity/,pinf); sub(/negative_infinity/,ninf); 
sub(/fmtspcl/,(sd"/fmtspcl")); print}' < "$(srcdir)"/fmtspcl.tok > $@ 
2>/dev/null
+fmtspcl.ok: fmtspcl.tok Makefile fix-fmtspcl.awk
+       @$(AWK) -v "sd=$(srcdir)" -f "$(srcdir)/fix-fmtspcl.awk" < 
"$(srcdir)"/fmtspcl.tok > $@ 2>/dev/null
 
 fmtspcl: fmtspcl.ok
        @echo $@
diff --git a/test/Makefile.in b/test/Makefile.in
index b987b1c..5b34a5a 100644
--- a/test/Makefile.in
+++ b/test/Makefile.in
@@ -536,6 +536,7 @@ EXTRA_DIST = \
        fieldwdth.ok \
        filefuncs.awk \
        filefuncs.ok \
+       fix-fmtspcl.awk \
        fldchg.awk \
        fldchg.in \
        fldchg.ok \
@@ -2132,8 +2133,8 @@ nors::
        @echo A B C D E | tr -d '\12\15' | $(AWK) '{ print $$NF }' - 
"$(srcdir)"/nors.in > _$@ || echo EXIT CODE: $$? >> _$@
        @-$(CMP) "$(srcdir)"/address@hidden _$@ && rm -f _$@
 
-fmtspcl.ok: fmtspcl.tok Makefile
-       @$(AWK) -v "sd=$(srcdir)" 'BEGIN {pnan = sprintf("%g",sqrt(-1)); nnan = 
sprintf("%g",-sqrt(-1)); pinf = sprintf("%g",-log(0)); ninf = 
sprintf("%g",log(0))} {sub(/positive_nan/,pnan); sub(/negative_nan/,nnan); 
sub(/positive_infinity/,pinf); sub(/negative_infinity/,ninf); 
sub(/fmtspcl/,(sd"/fmtspcl")); print}' < "$(srcdir)"/fmtspcl.tok > $@ 
2>/dev/null
+fmtspcl.ok: fmtspcl.tok Makefile fix-fmtspcl.awk
+       @$(AWK) -v "sd=$(srcdir)" -f "$(srcdir)/fix-fmtspcl.awk" < 
"$(srcdir)"/fmtspcl.tok > $@ 2>/dev/null
 
 fmtspcl: fmtspcl.ok
        @echo $@
diff --git a/test/fix-fmtspcl.awk b/test/fix-fmtspcl.awk
new file mode 100644
index 0000000..018f519
--- /dev/null
+++ b/test/fix-fmtspcl.awk
@@ -0,0 +1,23 @@
+BEGIN {
+       pnan = sprintf("%g",sqrt(-1))
+       nnan = sprintf("%g",-sqrt(-1))
+       pinf = sprintf("%g",-log(0))
+       ninf = sprintf("%g",log(0))
+
+       pnanu = toupper(pnan)
+       nnanu = toupper(nnan)
+       pinfu = toupper(pinf)
+       ninfu = toupper(ninf)
+}
+{
+       sub(/positive_nan/, pnan)
+       sub(/negative_nan/, nnan)
+       sub(/positive_infinity/, pinf)
+       sub(/negative_infinity/, ninf)
+       sub(/POSITIVE_NAN/, pnanu)
+       sub(/NEGATIVE_NAN/, nnanu)
+       sub(/POSITIVE_INFINITY/, pinfu)
+       sub(/NEGATIVE_INFINITY/, ninfu)
+       sub(/fmtspcl/,(sd "/fmtspcl"))
+       print
+}
diff --git a/test/fmtspcl.awk b/test/fmtspcl.awk
index eb99df6..b3313f7 100644
--- a/test/fmtspcl.awk
+++ b/test/fmtspcl.awk
@@ -8,14 +8,19 @@ function display(x, str,      i, res) {
 
 BEGIN {
        nan = sqrt(-1)
-       nan_str = sprintf("%f", nan)
-       nnan_str = sprintf("%f", -nan)
+       nan_str =  sprintf("%Pf", nan)
+       nnan_str = sprintf("%Pf", -nan)
+       if (nan_str == "nan")
+               nan_str = "+" nan_str
+       if (nnan_str == "nan")
+               nnan_str = "+" nnan_str
        inf = -log(0)
-       inf_str = sprintf("%f", inf)
-       ninf_str = sprintf("%f", -inf)
+       inf_str = "+" sprintf("%Pf", inf)
+       ninf_str = sprintf("%Pf", -inf)
 
        n = 0
        formats[n++] = "%a"
+       formats[n++] = "%e"
        formats[n++] = "%f"
        formats[n++] = "%g"
        formats[n++] = "%x"
diff --git a/test/fmtspcl.tok b/test/fmtspcl.tok
index 6fa0d1d..e85e170 100644
--- a/test/fmtspcl.tok
+++ b/test/fmtspcl.tok
@@ -1,10 +1,42 @@
 gawk: fmtspcl.awk:10: warning: sqrt: called with negative argument -1
 gawk: fmtspcl.awk:3: warning: %a format is POSIX standard but not portable to 
other awks
+gawk: fmtspcl.awk:3: warning: [s]printf: value positive_nan is out of range 
for `%a' format
+gawk: fmtspcl.awk:3: warning: [s]printf: value positive_nan is out of range 
for `%e' format
+gawk: fmtspcl.awk:3: warning: [s]printf: value positive_nan is out of range 
for `%f' format
+gawk: fmtspcl.awk:3: warning: [s]printf: value positive_nan is out of range 
for `%g' format
 gawk: fmtspcl.awk:3: warning: [s]printf: value positive_nan is out of range 
for `%x' format
 gawk: fmtspcl.awk:3: warning: [s]printf: value positive_nan is out of range 
for `%d' format
+gawk: fmtspcl.awk:3: warning: [s]printf: value negative_nan is out of range 
for `%a' format
+gawk: fmtspcl.awk:3: warning: [s]printf: value negative_nan is out of range 
for `%e' format
+gawk: fmtspcl.awk:3: warning: [s]printf: value negative_nan is out of range 
for `%f' format
+gawk: fmtspcl.awk:3: warning: [s]printf: value negative_nan is out of range 
for `%g' format
 gawk: fmtspcl.awk:3: warning: [s]printf: value negative_nan is out of range 
for `%x' format
 gawk: fmtspcl.awk:3: warning: [s]printf: value negative_nan is out of range 
for `%d' format
+gawk: fmtspcl.awk:3: warning: [s]printf: value positive_infinity is out of 
range for `%a' format
+gawk: fmtspcl.awk:3: warning: [s]printf: value positive_infinity is out of 
range for `%e' format
+gawk: fmtspcl.awk:3: warning: [s]printf: value positive_infinity is out of 
range for `%f' format
+gawk: fmtspcl.awk:3: warning: [s]printf: value positive_infinity is out of 
range for `%g' format
 gawk: fmtspcl.awk:3: warning: [s]printf: value positive_infinity is out of 
range for `%x' format
 gawk: fmtspcl.awk:3: warning: [s]printf: value positive_infinity is out of 
range for `%d' format
+gawk: fmtspcl.awk:3: warning: [s]printf: value negative_infinity is out of 
range for `%a' format
+gawk: fmtspcl.awk:3: warning: [s]printf: value negative_infinity is out of 
range for `%e' format
+gawk: fmtspcl.awk:3: warning: [s]printf: value negative_infinity is out of 
range for `%f' format
+gawk: fmtspcl.awk:3: warning: [s]printf: value negative_infinity is out of 
range for `%g' format
 gawk: fmtspcl.awk:3: warning: [s]printf: value negative_infinity is out of 
range for `%x' format
 gawk: fmtspcl.awk:3: warning: [s]printf: value negative_infinity is out of 
range for `%d' format
+gawk: fmtspcl.awk:3: warning: [s]printf: value POSITIVE_NAN is out of range 
for `%A' format
+gawk: fmtspcl.awk:3: warning: [s]printf: value POSITIVE_NAN is out of range 
for `%E' format
+gawk: fmtspcl.awk:3: warning: [s]printf: value POSITIVE_NAN is out of range 
for `%F' format
+gawk: fmtspcl.awk:3: warning: [s]printf: value POSITIVE_NAN is out of range 
for `%G' format
+gawk: fmtspcl.awk:3: warning: [s]printf: value NEGATIVE_NAN is out of range 
for `%A' format
+gawk: fmtspcl.awk:3: warning: [s]printf: value NEGATIVE_NAN is out of range 
for `%E' format
+gawk: fmtspcl.awk:3: warning: [s]printf: value NEGATIVE_NAN is out of range 
for `%F' format
+gawk: fmtspcl.awk:3: warning: [s]printf: value NEGATIVE_NAN is out of range 
for `%G' format
+gawk: fmtspcl.awk:3: warning: [s]printf: value POSITIVE_INFINITY is out of 
range for `%A' format
+gawk: fmtspcl.awk:3: warning: [s]printf: value POSITIVE_INFINITY is out of 
range for `%E' format
+gawk: fmtspcl.awk:3: warning: [s]printf: value POSITIVE_INFINITY is out of 
range for `%F' format
+gawk: fmtspcl.awk:3: warning: [s]printf: value POSITIVE_INFINITY is out of 
range for `%G' format
+gawk: fmtspcl.awk:3: warning: [s]printf: value NEGATIVE_INFINITY is out of 
range for `%A' format
+gawk: fmtspcl.awk:3: warning: [s]printf: value NEGATIVE_INFINITY is out of 
range for `%E' format
+gawk: fmtspcl.awk:3: warning: [s]printf: value NEGATIVE_INFINITY is out of 
range for `%F' format
+gawk: fmtspcl.awk:3: warning: [s]printf: value NEGATIVE_INFINITY is out of 
range for `%G' format
diff --git a/test/numrange.ok b/test/numrange.ok
index 006da13..73210bd 100644
--- a/test/numrange.ok
+++ b/test/numrange.ok
@@ -1,2 +1,2 @@
 -1.2e+931 -inf
-1.2e+931 inf
+1.2e+931 +inf

http://git.sv.gnu.org/cgit/gawk.git/commit/?id=18ff7b4b066fdd606a66e90b1f3b489840e09560

commit 18ff7b4b066fdd606a66e90b1f3b489840e09560
Author: Arnold D. Robbins <address@hidden>
Date:   Thu Jul 12 21:13:51 2018 +0300

    Improve fmtspcl test.

diff --git a/test/ChangeLog b/test/ChangeLog
index 0b41abb..b8816a5 100644
--- a/test/ChangeLog
+++ b/test/ChangeLog
@@ -1,3 +1,9 @@
+2018-07-12         Arnold D. Robbins     <address@hidden>
+
+       * fmtspcl.awk: Improve the formatting, add testing of uppercase
+       formats, fix a bug.
+       * fmtspcl.tok: Adjust for code changes.
+
 2018-06-22         Andrew J. Schorr     <address@hidden>
 
        * Makefile.am (EXTRA_DIST): Add files for numrange.
diff --git a/test/fmtspcl.awk b/test/fmtspcl.awk
index 6f037a3..eb99df6 100644
--- a/test/fmtspcl.awk
+++ b/test/fmtspcl.awk
@@ -1,26 +1,43 @@
-function display(x,str,  i,res) {
+function display(x, str,       i, res) {
        for (i = 0; i < n; i++) {
                if ((res = sprintf(formats[i],x)) != str)
                        printf "sprintf(%s,%s) = %s (!= %s)\n",
-                              formats[i],x,res,str
+                              formats[i], x, res, str
        }
 }
 
 BEGIN {
        nan = sqrt(-1)
-       nan_str = sprintf("%f",nan)
-       nnan_str = sprintf("%f",-nan)
+       nan_str = sprintf("%f", nan)
+       nnan_str = sprintf("%f", -nan)
        inf = -log(0)
-       inf_str = sprintf("%f",inf)
+       inf_str = sprintf("%f", inf)
+       ninf_str = sprintf("%f", -inf)
 
        n = 0
+       formats[n++] = "%a"
        formats[n++] = "%f"
-       formats[n++] = "%s"
        formats[n++] = "%g"
        formats[n++] = "%x"
        formats[n++] = "%d"
-       display(nan,nan_str)
-       display(-nan,nnan_str)
-       display(inf,inf)
-       display(-inf,"-"inf_str)
+       formats[n++] = "%s"
+       display(nan, nan_str)
+       display(-nan, nnan_str)
+       display(inf, inf_str)
+       display(-inf, ninf_str)
+
+       # Now test uppercase floating-point format strings
+       for (j = 0; j < n; j++)
+               formats[j] = toupper(formats[j])
+
+       n -= 3          # interger and string formats don't count (%x, %d, %s)
+       nan_str = toupper(nan_str)
+       nnan_str = toupper(nnan_str)
+       inf_str = toupper(inf_str)
+       ninf_str = toupper(ninf_str)
+
+       display(nan, nan_str)
+       display(-nan, nnan_str)
+       display(inf, inf_str)
+       display(-inf, ninf_str)
 }
diff --git a/test/fmtspcl.tok b/test/fmtspcl.tok
index ba823b8..6fa0d1d 100644
--- a/test/fmtspcl.tok
+++ b/test/fmtspcl.tok
@@ -1,4 +1,5 @@
 gawk: fmtspcl.awk:10: warning: sqrt: called with negative argument -1
+gawk: fmtspcl.awk:3: warning: %a format is POSIX standard but not portable to 
other awks
 gawk: fmtspcl.awk:3: warning: [s]printf: value positive_nan is out of range 
for `%x' format
 gawk: fmtspcl.awk:3: warning: [s]printf: value positive_nan is out of range 
for `%d' format
 gawk: fmtspcl.awk:3: warning: [s]printf: value negative_nan is out of range 
for `%x' format

-----------------------------------------------------------------------

Summary of changes:
 ChangeLog            |  16 +
 awk.h                |   2 +
 builtin.c            | 124 ++++++-
 doc/ChangeLog        |   7 +
 doc/gawk.info        | 920 ++++++++++++++++++++++++++-------------------------
 doc/gawk.texi        |  27 +-
 doc/gawktexi.in      |  27 +-
 mpfr.c               |   5 +
 node.c               |   7 +-
 test/ChangeLog       |  14 +
 test/Makefile.am     |   5 +-
 test/Makefile.in     |   5 +-
 test/fix-fmtspcl.awk |  23 ++
 test/fmtspcl.awk     |  42 ++-
 test/fmtspcl.tok     |  33 ++
 test/numrange.ok     |   2 +-
 16 files changed, 773 insertions(+), 486 deletions(-)
 create mode 100644 test/fix-fmtspcl.awk


hooks/post-receive
-- 
gawk



reply via email to

[Prev in Thread] Current Thread [Next in Thread]