summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArnold D. Robbins <arnold@skeeve.com>2018-07-13 13:56:10 +0300
committerArnold D. Robbins <arnold@skeeve.com>2018-07-13 13:56:10 +0300
commit8dba5f4c900239d01897e2197ddd79bcf5d9b034 (patch)
treeef1ede8e0f191df3b41df219f4a98fbbe3b0d9d2
parent18ff7b4b066fdd606a66e90b1f3b489840e09560 (diff)
downloadgawk-8dba5f4c900239d01897e2197ddd79bcf5d9b034.tar.gz
Output +inf, +nan etc. also, so that output can be input. Doc, tests, fixed.
-rw-r--r--ChangeLog16
-rw-r--r--awk.h2
-rw-r--r--builtin.c124
-rw-r--r--doc/ChangeLog7
-rw-r--r--doc/gawk.info920
-rw-r--r--doc/gawk.texi27
-rw-r--r--doc/gawktexi.in27
-rw-r--r--mpfr.c5
-rw-r--r--node.c7
-rw-r--r--test/ChangeLog8
-rw-r--r--test/Makefile.am5
-rw-r--r--test/Makefile.in5
-rw-r--r--test/fix-fmtspcl.awk23
-rw-r--r--test/fmtspcl.awk13
-rw-r--r--test/fmtspcl.tok32
-rw-r--r--test/numrange.ok2
16 files changed, 743 insertions, 480 deletions
diff --git a/ChangeLog b/ChangeLog
index 947e46da..8e2c226b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,19 @@
+2018-07-13 Arnold D. Robbins <arnold@skeeve.com>
+
+ * 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 <arnold@skeeve.com>
* config.guess, config.sub: Updated from GNULIB.
diff --git a/awk.h b/awk.h
index 31e661d4..a6d8193d 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 c54be9b2..44c484f5 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 33834a29..3f05800c 100644
--- a/doc/ChangeLog
+++ b/doc/ChangeLog
@@ -1,3 +1,10 @@
+2018-07-10 Arnold D. Robbins <arnold@skeeve.com>
+
+ * 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 <arnold@skeeve.com>
* texinfo.tex: Updated.
diff --git a/doc/gawk.info b/doc/gawk.info
index 29051f64..dc1aa075 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 7da5048c..3b7c2bf2 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
+@quotation 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
+@ref{POSIX Floating Point Problems}; please see there.
+@end 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 @}'}
-@print{} nan
+@print{} +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 a9a670db..8c4cb893 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
+@quotation 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
+@ref{POSIX Floating Point Problems}; please see there.
+@end 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 @}'}
-@print{} nan
+@print{} +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 0c962c67..b6e9c16e 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 984cec81..54ea6627 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 b8816a5f..2d85c9a9 100644
--- a/test/ChangeLog
+++ b/test/ChangeLog
@@ -1,3 +1,11 @@
+2018-07-13 Arnold D. Robbins <arnold@skeeve.com>
+
+ * 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 <arnold@skeeve.com>
* fmtspcl.awk: Improve the formatting, add testing of uppercase
diff --git a/test/Makefile.am b/test/Makefile.am
index e4cca53d..4ab96409 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)"/$@.ok _$@ && 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 b987b1c2..5b34a5ad 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)"/$@.ok _$@ && 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 00000000..018f519d
--- /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 eb99df65..b3313f77 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 6fa0d1da..e85e170c 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 006da13a..73210bd3 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