aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog13
-rw-r--r--NEWS8
-rw-r--r--awk.h9
-rw-r--r--awklib/eg/test-programs/gen-float-table.awk59
-rw-r--r--awklib/eg/test-programs/gen-float-table.c60
-rw-r--r--awklib/eg/test-programs/gen-float-table.py42
-rw-r--r--builtin.c2
-rw-r--r--doc/ChangeLog27
-rw-r--r--doc/gawk.info1284
-rw-r--r--doc/gawk.texi273
-rw-r--r--doc/gawktexi.in273
-rw-r--r--doc/it/ChangeLog4
-rwxr-xr-x[-rw-r--r--]doc/it/gawktexi.in308
-rw-r--r--doc/wordlist2
-rw-r--r--eval.c96
-rw-r--r--interpret.h12
-rw-r--r--mpfr.c44
-rw-r--r--node.c3
18 files changed, 1802 insertions, 717 deletions
diff --git a/ChangeLog b/ChangeLog
index ad396031..9089016b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -106,6 +106,19 @@
2020-11-02 Arnold D. Robbins <arnold@skeeve.com>
+ Make gawk numeric comparisons act like C doubles.
+ MPFR differs from doubles w.r.t. NaN, not sure why yet.
+
+ * awk.h (scalar_cmp_t): New enum.
+ * builtin.c (format_nan_inf): Use mpfr_signbit, not mpfr_sgn.
+ * eval.c (cmp_doubles): New routine.
+ (cmp_scalars): Change type to bool, rework logic.
+ * interpret.h (r_interpret): Rework scalar comparisons.
+ * mpfr.c (mpg_cmp_as_numbers): New routine.
+ * node.c: Use <math.h>, not "math.h", minor comment edits.
+
+2020-11-02 Arnold D. Robbins <arnold@skeeve.com>
+
* re.c (make_regexp): Cast len parameter to int to avoid
compiler warnings.
diff --git a/NEWS b/NEWS
index 9eae6480..891fff42 100644
--- a/NEWS
+++ b/NEWS
@@ -4,6 +4,14 @@
are permitted in any medium without royalty provided the copyright
notice and this notice are preserved.
+Changes from 5.1.x to 5.2.0
+---------------------------
+
+1. Numeric scalars now compare in the same way as C for the relational
+operators. Comparison order for sorting has not changed. This only
+makes a difference when comparing Infinity and NaN values with
+regular numbers; it should not be noticeable most of the time.
+
Changes from 5.1.0 to 5.1.1
---------------------------
diff --git a/awk.h b/awk.h
index 2ab25bfd..c9eec663 100644
--- a/awk.h
+++ b/awk.h
@@ -1576,6 +1576,15 @@ typedef enum {
extern field_sep_type current_field_sep(void);
extern const char *current_field_sep_str(void);
+typedef enum {
+ SCALAR_EQ,
+ SCALAR_NEQ,
+ SCALAR_LT,
+ SCALAR_LE,
+ SCALAR_GT,
+ SCALAR_GE,
+} scalar_cmp_t;
+
/* gawkapi.c: */
extern gawk_api_t api_impl;
extern void init_ext_api(void);
diff --git a/awklib/eg/test-programs/gen-float-table.awk b/awklib/eg/test-programs/gen-float-table.awk
new file mode 100644
index 00000000..c35f2dff
--- /dev/null
+++ b/awklib/eg/test-programs/gen-float-table.awk
@@ -0,0 +1,59 @@
+function eq(left, right)
+{
+ return left == right
+}
+
+function ne(left, right)
+{
+ return left != right
+}
+
+function lt(left, right)
+{
+ return left < right
+}
+
+function le(left, right)
+{
+ return left <= right
+}
+
+function gt(left, right)
+{
+ return left > right
+}
+
+function ge(left, right)
+{
+ return left >= right
+}
+
+BEGIN {
+ nan = sqrt(-1)
+ inf = -log(0)
+ split("== != < <= > >=", names)
+ names[3] = names[3] " "
+ names[5] = names[5] " "
+ split("eq ne lt le gt ge", funcs)
+
+ compare[1] = 2.0
+ compare[2] = values[1] = -sqrt(-1.0) # nan
+ compare[3] = values[2] = sqrt(-1.0) # -nan
+ compare[4] = values[3] = -log(0.0) # inf
+ compare[5] = values[4] = log(0.0) # -inf
+
+ for (i = 1; i in values; i++) {
+ for (j = 1; j in compare; j++) {
+ for (k = 1; k in names; k++) {
+ the_func = funcs[k]
+ printf("%g %s %g -> %s\n",
+ values[i],
+ names[k],
+ compare[j],
+ the_func(values[i], compare[j]) ?
+ "true" : "false");
+ }
+ printf("\n");
+ }
+ }
+}
diff --git a/awklib/eg/test-programs/gen-float-table.c b/awklib/eg/test-programs/gen-float-table.c
new file mode 100644
index 00000000..ae1d5dd4
--- /dev/null
+++ b/awklib/eg/test-programs/gen-float-table.c
@@ -0,0 +1,60 @@
+#include <stdio.h>
+#include <math.h>
+#include <stdbool.h>
+
+#define def_func(name, op) \
+ bool name(double left, double right) { \
+ return left op right; \
+ }
+
+def_func(eq, ==)
+def_func(ne, !=)
+def_func(lt, <)
+def_func(le, <=)
+def_func(gt, >)
+def_func(ge, >=)
+
+struct {
+ const char *name;
+ bool (*func)(double left, double right);
+} functions[] = {
+ { "==", eq },
+ { "!=", ne },
+ { "< ", lt },
+ { "<=", le },
+ { "> ", gt },
+ { ">=", ge },
+ { 0, 0 }
+};
+
+int main()
+{
+ double values[] = {
+ -sqrt(-1), // nan
+ sqrt(-1), // -nan
+ -log(0.0), // inf
+ log(0.0) // -inf
+ };
+ double compare[] = { 2.0,
+ -sqrt(-1), // nan
+ sqrt(-1), // -nan
+ -log(0.0), // inf
+ log(0.0) // -inf
+ };
+
+ int i, j, k;
+
+ for (i = 0; i < 4; i++) {
+ for (j = 0; j < 5; j++) {
+ for (k = 0; functions[k].name != NULL; k++) {
+ printf("%g %s %g -> %s\n", values[i],
+ functions[k].name,
+ compare[j],
+ functions[k].func(values[i], compare[j]) ? "true" : "false");
+ }
+ printf("\n");
+ }
+ }
+
+ return 0;
+}
diff --git a/awklib/eg/test-programs/gen-float-table.py b/awklib/eg/test-programs/gen-float-table.py
new file mode 100644
index 00000000..8631b817
--- /dev/null
+++ b/awklib/eg/test-programs/gen-float-table.py
@@ -0,0 +1,42 @@
+from math import *
+
+nan = float('NaN')
+inf = float('Inf')
+
+def eq(left, right):
+ return left == right
+
+def ne(left, right):
+ return left != right
+
+def lt(left, right):
+ return left < right
+
+def le(left, right):
+ return left <= right
+
+def gt(left, right):
+ return left > right
+
+def ge(left, right):
+ return left >= right
+
+func_map = {
+ "==": eq,
+ "!=": ne,
+ "< ": lt,
+ "<=": le,
+ "> ": gt,
+ ">=": ge,
+}
+
+compare = [2.0, nan, -nan, inf, -inf]
+values = [nan, -nan, inf, -inf]
+
+for i in range(len(values)):
+ for j in range(len(compare)):
+ for op in func_map:
+ print("%g %s %g -> %s" %
+ (values[i], op, compare[j], func_map[op](values[i], compare[j])))
+
+ print("")
diff --git a/builtin.c b/builtin.c
index e28c35ef..1b612f4a 100644
--- a/builtin.c
+++ b/builtin.c
@@ -4277,7 +4277,7 @@ format_nan_inf(NODE *n, char format)
goto fmt;
} else if (mpfr_inf_p(n->mpg_numbr)) {
- strcpy(buf, mpfr_sgn(n->mpg_numbr) < 0 ? "-inf" : "+inf");
+ strcpy(buf, mpfr_signbit(n->mpg_numbr) ? "-inf" : "+inf");
goto fmt;
} else
diff --git a/doc/ChangeLog b/doc/ChangeLog
index 416147dd..6cf1fdb2 100644
--- a/doc/ChangeLog
+++ b/doc/ChangeLog
@@ -48,12 +48,39 @@
* gawkworkflow.texi: Add an additional web resource.
* gawktexi.in: More edits in sample programs chapter.
+2020-11-20 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in (Strange values): Correct the description of what
+ happens with infinity. Thanks to Antonio Columbo for pointing
+ out the problem.
+
2020-11-16 Arnold D. Robbins <arnold@skeeve.com>
* gawktexi.in (Nextfile Statement): Clarify what happens in
a BEGINFILE rule.
* gawktexi.in: Additional small fixes.
+2020-11-15 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in (Strange values): Add test programs inside
+ @ignore; extracted to example directory.
+
+2020-11-09 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: Samll improvement in strange numbers section.
+
+2020-11-04 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in (Strange values): New section on NaN and infinity.
+ Update some other bits to point to it.
+ * wordlist: Updated with more words.
+
+2020-11-16 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in (Nextfile Statement): Clarify what happens in
+ a BEGINFILE rule.
+>>>>>>> master
+
2020-10-31 Arnold D. Robbins <arnold@skeeve.com>
* texinfo.tex: Updated from GNULIB.
diff --git a/doc/gawk.info b/doc/gawk.info
index 1557359e..bf9a88d7 100644
--- a/doc/gawk.info
+++ b/doc/gawk.info
@@ -547,6 +547,7 @@ in (a) below. A copy of the license is included in the section entitled
* Inexact representation:: Numbers are not exactly represented.
* Comparing FP Values:: How to compare floating point values.
* Errors accumulate:: Errors get bigger as they go.
+* Strange values:: A few words about infinities and NaNs.
* Getting Accuracy:: Getting more accuracy takes some work.
* Try To Round:: Add digits and round.
* Setting precision:: How to set the precision.
@@ -6933,8 +6934,8 @@ width. Here is a list of the format-control letters:
On systems supporting IEEE 754 floating-point format, values
representing negative infinity are formatted as '-inf' or
'-infinity', and positive infinity as 'inf' or 'infinity'. The
- special "not a number" value formats as '-nan' or 'nan' (*note Math
- Definitions::).
+ special "not a number" value formats as '-nan' or 'nan' (*note
+ Strange values::).
'%F'
Like '%f', but the infinity and "not a number" values are spelled
@@ -12826,7 +12827,7 @@ brackets ([ ]):
'log(X)'
Return the natural logarithm of X, if X is positive; otherwise,
- return 'NaN' ("not a number") on IEEE 754 systems. Additionally,
+ return NaN ("not a number") on IEEE 754 systems. Additionally,
'gawk' prints a warning message when 'x' is negative.
'rand()'
@@ -24209,18 +24210,10 @@ material here:
another number and infinity produce infinity.
"NaN"
- "Not a number."(1) A special value that results from attempting a
- calculation that has no answer as a real number. In such a case,
- programs can either receive a floating-point exception, or get
- 'NaN' back as the result. The IEEE 754 standard recommends that
- systems return 'NaN'. Some examples:
-
- 'sqrt(-1)'
- This makes sense in the range of complex numbers, but not in
- the range of real numbers, so the result is 'NaN'.
-
- 'log(-8)'
- -8 is out of the domain of 'log()', so the result is 'NaN'.
+ "Not a number." A special value that results from attempting a
+ calculation that has no answer as a real number. *Note Strange
+ values::, for more information about infinity and not-a-number
+ values.
"Normalized"
How the significand (see later in this list) is usually stored.
@@ -24279,11 +24272,6 @@ Table 16.3: Basic IEEE format values
NOTE: The precision numbers include the implied leading one that
gives them one extra bit of significand.
- ---------- Footnotes ----------
-
- (1) Thanks to Michael Brennan for this description, which we have
-paraphrased, and for the examples.
-

File: gawk.info, Node: MPFR features, Next: FP Math Caution, Prev: Math Definitions, Up: Arbitrary Precision Arithmetic
@@ -24376,6 +24364,7 @@ be sure of the number of significant decimal places in the final result.
* Inexact representation:: Numbers are not exactly represented.
* Comparing FP Values:: How to compare floating point values.
* Errors accumulate:: Errors get bigger as they go.
+* Strange values:: A few words about infinities and NaNs.

File: gawk.info, Node: Inexact representation, Next: Comparing FP Values, Up: Inexactness of computations
@@ -24440,7 +24429,7 @@ values with a delta, you should be sure to use 'difference < abs(delta)'
in case someone passes in a negative delta value.

-File: gawk.info, Node: Errors accumulate, Prev: Comparing FP Values, Up: Inexactness of computations
+File: gawk.info, Node: Errors accumulate, Next: Strange values, Prev: Comparing FP Values, Up: Inexactness of computations
16.4.1.3 Errors Accumulate
..........................
@@ -24488,6 +24477,64 @@ representations yield an unexpected result:
-| 4

+File: gawk.info, Node: Strange values, Prev: Errors accumulate, Up: Inexactness of computations
+
+16.4.1.4 Floating Point Values They Didn't Talk About In School
+...............................................................
+
+Both IEEE 754 floating-point hardware, and MPFR, support two kinds of
+values that you probably didn't learn about in school. The first is
+"infinity", a special value, that can be either negative or positive,
+and which is either smaller than any other value (negative infinity), or
+larger than any other value (positive infinity). When such values are
+generated, 'gawk' prints them as either '-inf' or '+inf', respectively.
+It accepts those strings as data input and converts them to the proper
+floating-point values internally.
+
+ Infinity values of the same sign compare as equal to each other.
+Otherwise, operations (addition, subtraction, etc.) involving another
+number and infinity produce mathematically reasonable results.
+
+ The second kind of value is "not a number", or NaN for short.(1)
+This is a special value that results from attempting a calculation that
+has no answer as a real number. In such a case, programs can either
+receive a floating-point exception, or get NaN back as the result. The
+IEEE 754 standard recommends that systems return NaN. Some examples:
+
+'sqrt(-1)'
+ This makes sense in the range of complex numbers, but not in the
+ range of real numbers, so the result is NaN.
+
+'log(-8)'
+ -8 is out of the domain of 'log()', so the result is NaN.
+
+ NaN values are strange. In particular, they cannot be compared with
+other floating point values; any such comparison, except for "is not
+equal to", returns false. NaN values are so much unequal to other
+values that even comparing two identical NaN values with '!=' returns
+true!
+
+ NaN values can also be signed, although it depends upon the
+implementation as to which sign you get for any operation that returns a
+NaN. For example, on some systems, 'sqrt(-1)' returns a negative NaN. On
+others, it returns a positive NaN.
+
+ When such values are generated, 'gawk' prints them as either '-nan'
+or '+nan', respectively. Here too, 'gawk' accepts those strings as data
+input and converts them to the proper floating-point values internally.
+
+ If you want to dive more deeply into this topic, you can find test
+programs in C, 'awk' and Python in the directory
+'awklib/eg/test-programs' in the 'gawk' distribution. These programs
+enable comparison among programming languages as to how they handle NaN
+and infinity values.
+
+ ---------- Footnotes ----------
+
+ (1) Thanks to Michael Brennan for this description, which we have
+paraphrased, and for the examples.
+
+
File: gawk.info, Node: Getting Accuracy, Next: Try To Round, Prev: Inexactness of computations, Up: FP Math Caution
16.4.2 Getting the Accuracy You Need
@@ -38002,603 +38049,604 @@ Index

Tag Table:
Node: Top1200
-Node: Foreword344559
-Node: Foreword449001
-Node: Preface50533
-Ref: Preface-Footnote-153392
-Ref: Preface-Footnote-253501
-Ref: Preface-Footnote-353735
-Node: History53877
-Node: Names56229
-Ref: Names-Footnote-157333
-Node: This Manual57480
-Ref: This Manual-Footnote-164119
-Node: Conventions64219
-Node: Manual History66588
-Ref: Manual History-Footnote-169585
-Ref: Manual History-Footnote-269626
-Node: How To Contribute69700
-Node: Acknowledgments70626
-Node: Getting Started75563
-Node: Running gawk78002
-Node: One-shot79192
-Node: Read Terminal80455
-Node: Long82448
-Node: Executable Scripts83961
-Ref: Executable Scripts-Footnote-186594
-Node: Comments86697
-Node: Quoting89181
-Node: DOS Quoting94707
-Node: Sample Data Files96763
-Node: Very Simple99358
-Node: Two Rules105460
-Node: More Complex107345
-Node: Statements/Lines109677
-Ref: Statements/Lines-Footnote-1114161
-Node: Other Features114426
-Node: When115362
-Ref: When-Footnote-1117116
-Node: Intro Summary117181
-Node: Invoking Gawk118065
-Node: Command Line119579
-Node: Options120377
-Ref: Options-Footnote-1138291
-Ref: Options-Footnote-2138522
-Node: Other Arguments138547
-Node: Naming Standard Input142558
-Node: Environment Variables143768
-Node: AWKPATH Variable144326
-Ref: AWKPATH Variable-Footnote-1147738
-Ref: AWKPATH Variable-Footnote-2147772
-Node: AWKLIBPATH Variable148143
-Ref: AWKLIBPATH Variable-Footnote-1149840
-Node: Other Environment Variables150215
-Node: Exit Status154036
-Node: Include Files154713
-Node: Loading Shared Libraries158403
-Node: Obsolete159831
-Node: Undocumented160523
-Node: Invoking Summary160820
-Node: Regexp163661
-Node: Regexp Usage165115
-Node: Escape Sequences167152
-Node: Regexp Operators173393
-Node: Regexp Operator Details173878
-Ref: Regexp Operator Details-Footnote-1180310
-Node: Interval Expressions180457
-Ref: Interval Expressions-Footnote-1181878
-Node: Bracket Expressions181976
-Ref: table-char-classes184452
-Node: Leftmost Longest187778
-Node: Computed Regexps189081
-Node: GNU Regexp Operators192508
-Node: Case-sensitivity196245
-Ref: Case-sensitivity-Footnote-1199111
-Ref: Case-sensitivity-Footnote-2199346
-Node: Regexp Summary199454
-Node: Reading Files200920
-Node: Records203189
-Node: awk split records204264
-Node: gawk split records208964
-Ref: gawk split records-Footnote-1214038
-Node: Fields214075
-Node: Nonconstant Fields216816
-Ref: Nonconstant Fields-Footnote-1219052
-Node: Changing Fields219256
-Node: Field Separators225287
-Node: Default Field Splitting227985
-Node: Regexp Field Splitting229103
-Node: Single Character Fields232780
-Node: Command Line Field Separator233840
-Node: Full Line Fields237058
-Ref: Full Line Fields-Footnote-1238580
-Ref: Full Line Fields-Footnote-2238626
-Node: Field Splitting Summary238727
-Node: Constant Size240801
-Node: Fixed width data241533
-Node: Skipping intervening245000
-Node: Allowing trailing data245798
-Node: Fields with fixed data246835
-Node: Splitting By Content248353
-Ref: Splitting By Content-Footnote-1252136
-Node: More CSV252299
-Node: Testing field creation253891
-Node: Multiple Line255516
-Node: Getline261793
-Node: Plain Getline264262
-Node: Getline/Variable266835
-Node: Getline/File267986
-Node: Getline/Variable/File269374
-Ref: Getline/Variable/File-Footnote-1270979
-Node: Getline/Pipe271067
-Node: Getline/Variable/Pipe273771
-Node: Getline/Coprocess274906
-Node: Getline/Variable/Coprocess276173
-Node: Getline Notes276915
-Node: Getline Summary279712
-Ref: table-getline-variants280136
-Node: Read Timeout280884
-Ref: Read Timeout-Footnote-1284790
-Node: Retrying Input284848
-Node: Command-line directories286047
-Node: Input Summary286953
-Node: Input Exercises290125
-Node: Printing290559
-Node: Print292393
-Node: Print Examples293850
-Node: Output Separators296630
-Node: OFMT298647
-Node: Printf300003
-Node: Basic Printf300788
-Node: Control Letters302362
-Node: Format Modifiers307526
-Node: Printf Examples313541
-Node: Redirection316027
-Node: Special FD322868
-Ref: Special FD-Footnote-1326036
-Node: Special Files326110
-Node: Other Inherited Files326727
-Node: Special Network327728
-Node: Special Caveats328588
-Node: Close Files And Pipes329537
-Ref: table-close-pipe-return-values336444
-Ref: Close Files And Pipes-Footnote-1337257
-Ref: Close Files And Pipes-Footnote-2337405
-Node: Nonfatal337557
-Node: Output Summary339895
-Node: Output Exercises341117
-Node: Expressions341796
-Node: Values342984
-Node: Constants343662
-Node: Scalar Constants344353
-Ref: Scalar Constants-Footnote-1346863
-Node: Nondecimal-numbers347113
-Node: Regexp Constants350114
-Node: Using Constant Regexps350640
-Node: Standard Regexp Constants351262
-Node: Strong Regexp Constants354450
-Node: Variables357462
-Node: Using Variables358119
-Node: Assignment Options360029
-Node: Conversion362500
-Node: Strings And Numbers363024
-Ref: Strings And Numbers-Footnote-1366087
-Node: Locale influences conversions366196
-Ref: table-locale-affects368954
-Node: All Operators369572
-Node: Arithmetic Ops370201
-Node: Concatenation372917
-Ref: Concatenation-Footnote-1375764
-Node: Assignment Ops375871
-Ref: table-assign-ops380862
-Node: Increment Ops382175
-Node: Truth Values and Conditions385635
-Node: Truth Values386709
-Node: Typing and Comparison387757
-Node: Variable Typing388577
-Ref: Variable Typing-Footnote-1395040
-Ref: Variable Typing-Footnote-2395112
-Node: Comparison Operators395189
-Ref: table-relational-ops395608
-Node: POSIX String Comparison399103
-Ref: POSIX String Comparison-Footnote-1400798
-Ref: POSIX String Comparison-Footnote-2400937
-Node: Boolean Ops401021
-Ref: Boolean Ops-Footnote-1405503
-Node: Conditional Exp405595
-Node: Function Calls407331
-Node: Precedence411208
-Node: Locales414867
-Node: Expressions Summary416499
-Node: Patterns and Actions419072
-Node: Pattern Overview420192
-Node: Regexp Patterns421869
-Node: Expression Patterns422411
-Node: Ranges426192
-Node: BEGIN/END429300
-Node: Using BEGIN/END430061
-Ref: Using BEGIN/END-Footnote-1432815
-Node: I/O And BEGIN/END432921
-Node: BEGINFILE/ENDFILE435234
-Node: Empty438465
-Node: Using Shell Variables438782
-Node: Action Overview441056
-Node: Statements443381
-Node: If Statement445229
-Node: While Statement446724
-Node: Do Statement448752
-Node: For Statement449900
-Node: Switch Statement453071
-Node: Break Statement455512
-Node: Continue Statement457604
-Node: Next Statement459431
-Node: Nextfile Statement461814
-Node: Exit Statement464503
-Node: Built-in Variables466906
-Node: User-modified468039
-Node: Auto-set475806
-Ref: Auto-set-Footnote-1492613
-Ref: Auto-set-Footnote-2492819
-Node: ARGC and ARGV492875
-Node: Pattern Action Summary497088
-Node: Arrays499518
-Node: Array Basics500847
-Node: Array Intro501691
-Ref: figure-array-elements503666
-Ref: Array Intro-Footnote-1506370
-Node: Reference to Elements506498
-Node: Assigning Elements508962
-Node: Array Example509453
-Node: Scanning an Array511212
-Node: Controlling Scanning514234
-Ref: Controlling Scanning-Footnote-1520690
-Node: Numeric Array Subscripts521006
-Node: Uninitialized Subscripts523190
-Node: Delete524809
-Ref: Delete-Footnote-1527561
-Node: Multidimensional527618
-Node: Multiscanning530713
-Node: Arrays of Arrays532304
-Node: Arrays Summary537072
-Node: Functions539165
-Node: Built-in540203
-Node: Calling Built-in541284
-Node: Numeric Functions543280
-Ref: Numeric Functions-Footnote-1547308
-Ref: Numeric Functions-Footnote-2547956
-Ref: Numeric Functions-Footnote-3548004
-Node: String Functions548276
-Ref: String Functions-Footnote-1572417
-Ref: String Functions-Footnote-2572545
-Ref: String Functions-Footnote-3572793
-Node: Gory Details572880
-Ref: table-sub-escapes574671
-Ref: table-sub-proposed576190
-Ref: table-posix-sub577553
-Ref: table-gensub-escapes579094
-Ref: Gory Details-Footnote-1579917
-Node: I/O Functions580071
-Ref: table-system-return-values586525
-Ref: I/O Functions-Footnote-1588605
-Ref: I/O Functions-Footnote-2588753
-Node: Time Functions588873
-Ref: Time Functions-Footnote-1599544
-Ref: Time Functions-Footnote-2599612
-Ref: Time Functions-Footnote-3599770
-Ref: Time Functions-Footnote-4599881
-Ref: Time Functions-Footnote-5599993
-Ref: Time Functions-Footnote-6600220
-Node: Bitwise Functions600486
-Ref: table-bitwise-ops601080
-Ref: Bitwise Functions-Footnote-1607143
-Ref: Bitwise Functions-Footnote-2607316
-Node: Type Functions607507
-Node: I18N Functions610370
-Node: User-defined612021
-Node: Definition Syntax612833
-Ref: Definition Syntax-Footnote-1618527
-Node: Function Example618598
-Ref: Function Example-Footnote-1621520
-Node: Function Calling621542
-Node: Calling A Function622130
-Node: Variable Scope623088
-Node: Pass By Value/Reference626082
-Node: Function Caveats628726
-Ref: Function Caveats-Footnote-1630773
-Node: Return Statement630893
-Node: Dynamic Typing633872
-Node: Indirect Calls634802
-Ref: Indirect Calls-Footnote-1645054
-Node: Functions Summary645182
-Node: Library Functions647887
-Ref: Library Functions-Footnote-1651494
-Ref: Library Functions-Footnote-2651637
-Node: Library Names651808
-Ref: Library Names-Footnote-1655475
-Ref: Library Names-Footnote-2655698
-Node: General Functions655784
-Node: Strtonum Function656887
-Node: Assert Function659909
-Node: Round Function663235
-Node: Cliff Random Function664775
-Node: Ordinal Functions665791
-Ref: Ordinal Functions-Footnote-1668854
-Ref: Ordinal Functions-Footnote-2669106
-Node: Join Function669316
-Ref: Join Function-Footnote-1671086
-Node: Getlocaltime Function671286
-Node: Readfile Function675028
-Node: Shell Quoting677005
-Node: Data File Management678406
-Node: Filetrans Function679038
-Node: Rewind Function683134
-Node: File Checking685043
-Ref: File Checking-Footnote-1686377
-Node: Empty Files686578
-Node: Ignoring Assigns688557
-Node: Getopt Function690107
-Ref: Getopt Function-Footnote-1705318
-Node: Passwd Functions705518
-Ref: Passwd Functions-Footnote-1714357
-Node: Group Functions714445
-Ref: Group Functions-Footnote-1722343
-Node: Walking Arrays722550
-Node: Library Functions Summary725558
-Node: Library Exercises726964
-Node: Sample Programs727429
-Node: Running Examples728199
-Node: Clones728927
-Node: Cut Program730151
-Node: Egrep Program740291
-Node: Id Program749302
-Node: Split Program759249
-Ref: Split Program-Footnote-1769139
-Node: Tee Program769312
-Node: Uniq Program772102
-Node: Wc Program779690
-Node: Bytes vs. Characters780087
-Node: Using extensions781635
-Node: wc program782389
-Node: Miscellaneous Programs787254
-Node: Dupword Program788467
-Node: Alarm Program790497
-Node: Translate Program795352
-Ref: Translate Program-Footnote-1799917
-Node: Labels Program800187
-Ref: Labels Program-Footnote-1803538
-Node: Word Sorting803622
-Node: History Sorting807694
-Node: Extract Program809919
-Node: Simple Sed817973
-Node: Igawk Program821047
-Ref: Igawk Program-Footnote-1835378
-Ref: Igawk Program-Footnote-2835580
-Ref: Igawk Program-Footnote-3835702
-Node: Anagram Program835817
-Node: Signature Program838879
-Node: Programs Summary840126
-Node: Programs Exercises841340
-Ref: Programs Exercises-Footnote-1845470
-Node: Advanced Features845556
-Node: Nondecimal Data847623
-Node: Array Sorting849214
-Node: Controlling Array Traversal849914
-Ref: Controlling Array Traversal-Footnote-1858282
-Node: Array Sorting Functions858400
-Ref: Array Sorting Functions-Footnote-1863491
-Node: Two-way I/O863687
-Ref: Two-way I/O-Footnote-1871408
-Ref: Two-way I/O-Footnote-2871595
-Node: TCP/IP Networking871677
-Node: Profiling874795
-Node: Extension Philosophy884104
-Node: Advanced Features Summary885555
-Node: Internationalization887554
-Node: I18N and L10N889034
-Node: Explaining gettext889721
-Ref: Explaining gettext-Footnote-1895613
-Ref: Explaining gettext-Footnote-2895798
-Node: Programmer i18n895963
-Ref: Programmer i18n-Footnote-1900912
-Node: Translator i18n900961
-Node: String Extraction901755
-Ref: String Extraction-Footnote-1902887
-Node: Printf Ordering902973
-Ref: Printf Ordering-Footnote-1905759
-Node: I18N Portability905823
-Ref: I18N Portability-Footnote-1908279
-Node: I18N Example908342
-Ref: I18N Example-Footnote-1911617
-Ref: I18N Example-Footnote-2911690
-Node: Gawk I18N911799
-Node: I18N Summary912448
-Node: Debugger913789
-Node: Debugging914789
-Node: Debugging Concepts915230
-Node: Debugging Terms917039
-Node: Awk Debugging919614
-Ref: Awk Debugging-Footnote-1920559
-Node: Sample Debugging Session920691
-Node: Debugger Invocation921225
-Node: Finding The Bug922611
-Node: List of Debugger Commands929085
-Node: Breakpoint Control930418
-Node: Debugger Execution Control934112
-Node: Viewing And Changing Data937474
-Node: Execution Stack941015
-Node: Debugger Info942652
-Node: Miscellaneous Debugger Commands946723
-Node: Readline Support951785
-Node: Limitations952681
-Node: Debugging Summary955235
-Node: Namespaces956514
-Node: Global Namespace957625
-Node: Qualified Names959023
-Node: Default Namespace960022
-Node: Changing The Namespace960763
-Node: Naming Rules962377
-Node: Internal Name Management964225
-Node: Namespace Example965267
-Node: Namespace And Features967829
-Node: Namespace Summary969264
-Node: Arbitrary Precision Arithmetic970741
-Node: Computer Arithmetic972228
-Ref: table-numeric-ranges975994
-Ref: table-floating-point-ranges976487
-Ref: Computer Arithmetic-Footnote-1977145
-Node: Math Definitions977202
-Ref: table-ieee-formats980518
-Ref: Math Definitions-Footnote-1981121
-Node: MPFR features981226
-Node: FP Math Caution982944
-Ref: FP Math Caution-Footnote-1984016
-Node: Inexactness of computations984385
-Node: Inexact representation985345
-Node: Comparing FP Values986705
-Node: Errors accumulate987946
-Node: Getting Accuracy989379
-Node: Try To Round992089
-Node: Setting precision992988
-Ref: table-predefined-precision-strings993685
-Node: Setting the rounding mode995515
-Ref: table-gawk-rounding-modes995889
-Ref: Setting the rounding mode-Footnote-1999820
-Node: Arbitrary Precision Integers999999
-Ref: Arbitrary Precision Integers-Footnote-11003174
-Node: Checking for MPFR1003323
-Node: POSIX Floating Point Problems1004797
-Ref: POSIX Floating Point Problems-Footnote-11009082
-Node: Floating point summary1009120
-Node: Dynamic Extensions1011310
-Node: Extension Intro1012863
-Node: Plugin License1014129
-Node: Extension Mechanism Outline1014926
-Ref: figure-load-extension1015365
-Ref: figure-register-new-function1016930
-Ref: figure-call-new-function1018022
-Node: Extension API Description1020084
-Node: Extension API Functions Introduction1021797
-Ref: table-api-std-headers1023633
-Node: General Data Types1027882
-Ref: General Data Types-Footnote-11036512
-Node: Memory Allocation Functions1036811
-Ref: Memory Allocation Functions-Footnote-11041312
-Node: Constructor Functions1041411
-Node: API Ownership of MPFR and GMP Values1044877
-Node: Registration Functions1046190
-Node: Extension Functions1046890
-Node: Exit Callback Functions1052212
-Node: Extension Version String1053462
-Node: Input Parsers1054125
-Node: Output Wrappers1066846
-Node: Two-way processors1071358
-Node: Printing Messages1073623
-Ref: Printing Messages-Footnote-11074794
-Node: Updating ERRNO1074947
-Node: Requesting Values1075686
-Ref: table-value-types-returned1076423
-Node: Accessing Parameters1077359
-Node: Symbol Table Access1078596
-Node: Symbol table by name1079108
-Ref: Symbol table by name-Footnote-11082132
-Node: Symbol table by cookie1082260
-Ref: Symbol table by cookie-Footnote-11086445
-Node: Cached values1086509
-Ref: Cached values-Footnote-11090045
-Node: Array Manipulation1090198
-Ref: Array Manipulation-Footnote-11091289
-Node: Array Data Types1091326
-Ref: Array Data Types-Footnote-11093984
-Node: Array Functions1094076
-Node: Flattening Arrays1098574
-Node: Creating Arrays1105550
-Node: Redirection API1110317
-Node: Extension API Variables1113150
-Node: Extension Versioning1113861
-Ref: gawk-api-version1114290
-Node: Extension GMP/MPFR Versioning1116021
-Node: Extension API Informational Variables1117649
-Node: Extension API Boilerplate1118722
-Node: Changes from API V11122696
-Node: Finding Extensions1124268
-Node: Extension Example1124827
-Node: Internal File Description1125625
-Node: Internal File Ops1129705
-Ref: Internal File Ops-Footnote-11141055
-Node: Using Internal File Ops1141195
-Ref: Using Internal File Ops-Footnote-11143578
-Node: Extension Samples1143852
-Node: Extension Sample File Functions1145381
-Node: Extension Sample Fnmatch1153030
-Node: Extension Sample Fork1154517
-Node: Extension Sample Inplace1155735
-Node: Extension Sample Ord1159361
-Node: Extension Sample Readdir1160197
-Ref: table-readdir-file-types1161086
-Node: Extension Sample Revout1162153
-Node: Extension Sample Rev2way1162742
-Node: Extension Sample Read write array1163482
-Node: Extension Sample Readfile1165424
-Node: Extension Sample Time1166519
-Node: Extension Sample API Tests1168271
-Node: gawkextlib1168763
-Node: Extension summary1171681
-Node: Extension Exercises1175383
-Node: Language History1176625
-Node: V7/SVR3.11178281
-Node: SVR41180433
-Node: POSIX1181867
-Node: BTL1183248
-Node: POSIX/GNU1183977
-Node: Feature History1189755
-Node: Common Extensions1206074
-Node: Ranges and Locales1207357
-Ref: Ranges and Locales-Footnote-11211973
-Ref: Ranges and Locales-Footnote-21212000
-Ref: Ranges and Locales-Footnote-31212235
-Node: Contributors1212458
-Node: History summary1218455
-Node: Installation1219835
-Node: Gawk Distribution1220779
-Node: Getting1221263
-Node: Extracting1222226
-Node: Distribution contents1223864
-Node: Unix Installation1230344
-Node: Quick Installation1231026
-Node: Shell Startup Files1233440
-Node: Additional Configuration Options1234529
-Node: Configuration Philosophy1236844
-Node: Non-Unix Installation1239213
-Node: PC Installation1239673
-Node: PC Binary Installation1240511
-Node: PC Compiling1240946
-Node: PC Using1242063
-Node: Cygwin1245616
-Node: MSYS1246840
-Node: VMS Installation1247442
-Node: VMS Compilation1248233
-Ref: VMS Compilation-Footnote-11249462
-Node: VMS Dynamic Extensions1249520
-Node: VMS Installation Details1251205
-Node: VMS Running1253458
-Node: VMS GNV1257737
-Node: VMS Old Gawk1258472
-Node: Bugs1258943
-Node: Bug address1259606
-Node: Usenet1262588
-Node: Maintainers1263592
-Node: Other Versions1264777
-Node: Installation summary1271865
-Node: Notes1273074
-Node: Compatibility Mode1273868
-Node: Additions1274650
-Node: Accessing The Source1275575
-Node: Adding Code1277012
-Node: New Ports1283231
-Node: Derived Files1287606
-Ref: Derived Files-Footnote-11293266
-Ref: Derived Files-Footnote-21293301
-Ref: Derived Files-Footnote-31293899
-Node: Future Extensions1294013
-Node: Implementation Limitations1294671
-Node: Extension Design1295881
-Node: Old Extension Problems1297025
-Ref: Old Extension Problems-Footnote-11298543
-Node: Extension New Mechanism Goals1298600
-Ref: Extension New Mechanism Goals-Footnote-11301964
-Node: Extension Other Design Decisions1302153
-Node: Extension Future Growth1304266
-Node: Notes summary1304872
-Node: Basic Concepts1306030
-Node: Basic High Level1306711
-Ref: figure-general-flow1306993
-Ref: figure-process-flow1307678
-Ref: Basic High Level-Footnote-11310979
-Node: Basic Data Typing1311164
-Node: Glossary1314492
-Node: Copying1346377
-Node: GNU Free Documentation License1383920
-Node: Index1409040
+Node: Foreword344638
+Node: Foreword449080
+Node: Preface50612
+Ref: Preface-Footnote-153471
+Ref: Preface-Footnote-253580
+Ref: Preface-Footnote-353814
+Node: History53956
+Node: Names56308
+Ref: Names-Footnote-157412
+Node: This Manual57559
+Ref: This Manual-Footnote-164198
+Node: Conventions64298
+Node: Manual History66667
+Ref: Manual History-Footnote-169664
+Ref: Manual History-Footnote-269705
+Node: How To Contribute69779
+Node: Acknowledgments70705
+Node: Getting Started75642
+Node: Running gawk78081
+Node: One-shot79271
+Node: Read Terminal80534
+Node: Long82527
+Node: Executable Scripts84040
+Ref: Executable Scripts-Footnote-186673
+Node: Comments86776
+Node: Quoting89260
+Node: DOS Quoting94786
+Node: Sample Data Files96842
+Node: Very Simple99437
+Node: Two Rules105539
+Node: More Complex107424
+Node: Statements/Lines109756
+Ref: Statements/Lines-Footnote-1114240
+Node: Other Features114505
+Node: When115441
+Ref: When-Footnote-1117195
+Node: Intro Summary117260
+Node: Invoking Gawk118144
+Node: Command Line119658
+Node: Options120456
+Ref: Options-Footnote-1138370
+Ref: Options-Footnote-2138601
+Node: Other Arguments138626
+Node: Naming Standard Input142637
+Node: Environment Variables143847
+Node: AWKPATH Variable144405
+Ref: AWKPATH Variable-Footnote-1147817
+Ref: AWKPATH Variable-Footnote-2147851
+Node: AWKLIBPATH Variable148222
+Ref: AWKLIBPATH Variable-Footnote-1149919
+Node: Other Environment Variables150294
+Node: Exit Status154115
+Node: Include Files154792
+Node: Loading Shared Libraries158482
+Node: Obsolete159910
+Node: Undocumented160602
+Node: Invoking Summary160899
+Node: Regexp163740
+Node: Regexp Usage165194
+Node: Escape Sequences167231
+Node: Regexp Operators173472
+Node: Regexp Operator Details173957
+Ref: Regexp Operator Details-Footnote-1180389
+Node: Interval Expressions180536
+Ref: Interval Expressions-Footnote-1181957
+Node: Bracket Expressions182055
+Ref: table-char-classes184531
+Node: Leftmost Longest187857
+Node: Computed Regexps189160
+Node: GNU Regexp Operators192587
+Node: Case-sensitivity196324
+Ref: Case-sensitivity-Footnote-1199190
+Ref: Case-sensitivity-Footnote-2199425
+Node: Regexp Summary199533
+Node: Reading Files200999
+Node: Records203268
+Node: awk split records204343
+Node: gawk split records209043
+Ref: gawk split records-Footnote-1214117
+Node: Fields214154
+Node: Nonconstant Fields216895
+Ref: Nonconstant Fields-Footnote-1219131
+Node: Changing Fields219335
+Node: Field Separators225366
+Node: Default Field Splitting228064
+Node: Regexp Field Splitting229182
+Node: Single Character Fields232859
+Node: Command Line Field Separator233919
+Node: Full Line Fields237137
+Ref: Full Line Fields-Footnote-1238659
+Ref: Full Line Fields-Footnote-2238705
+Node: Field Splitting Summary238806
+Node: Constant Size240880
+Node: Fixed width data241612
+Node: Skipping intervening245079
+Node: Allowing trailing data245877
+Node: Fields with fixed data246914
+Node: Splitting By Content248432
+Ref: Splitting By Content-Footnote-1252215
+Node: More CSV252378
+Node: Testing field creation253970
+Node: Multiple Line255595
+Node: Getline261872
+Node: Plain Getline264341
+Node: Getline/Variable266914
+Node: Getline/File268065
+Node: Getline/Variable/File269453
+Ref: Getline/Variable/File-Footnote-1271058
+Node: Getline/Pipe271146
+Node: Getline/Variable/Pipe273850
+Node: Getline/Coprocess274985
+Node: Getline/Variable/Coprocess276252
+Node: Getline Notes276994
+Node: Getline Summary279791
+Ref: table-getline-variants280215
+Node: Read Timeout280963
+Ref: Read Timeout-Footnote-1284869
+Node: Retrying Input284927
+Node: Command-line directories286126
+Node: Input Summary287032
+Node: Input Exercises290204
+Node: Printing290638
+Node: Print292472
+Node: Print Examples293929
+Node: Output Separators296709
+Node: OFMT298726
+Node: Printf300082
+Node: Basic Printf300867
+Node: Control Letters302441
+Node: Format Modifiers307603
+Node: Printf Examples313618
+Node: Redirection316104
+Node: Special FD322945
+Ref: Special FD-Footnote-1326113
+Node: Special Files326187
+Node: Other Inherited Files326804
+Node: Special Network327805
+Node: Special Caveats328665
+Node: Close Files And Pipes329614
+Ref: table-close-pipe-return-values336521
+Ref: Close Files And Pipes-Footnote-1337334
+Ref: Close Files And Pipes-Footnote-2337482
+Node: Nonfatal337634
+Node: Output Summary339972
+Node: Output Exercises341194
+Node: Expressions341873
+Node: Values343061
+Node: Constants343739
+Node: Scalar Constants344430
+Ref: Scalar Constants-Footnote-1346940
+Node: Nondecimal-numbers347190
+Node: Regexp Constants350191
+Node: Using Constant Regexps350717
+Node: Standard Regexp Constants351339
+Node: Strong Regexp Constants354527
+Node: Variables357539
+Node: Using Variables358196
+Node: Assignment Options360106
+Node: Conversion362577
+Node: Strings And Numbers363101
+Ref: Strings And Numbers-Footnote-1366164
+Node: Locale influences conversions366273
+Ref: table-locale-affects369031
+Node: All Operators369649
+Node: Arithmetic Ops370278
+Node: Concatenation372994
+Ref: Concatenation-Footnote-1375841
+Node: Assignment Ops375948
+Ref: table-assign-ops380939
+Node: Increment Ops382252
+Node: Truth Values and Conditions385712
+Node: Truth Values386786
+Node: Typing and Comparison387834
+Node: Variable Typing388654
+Ref: Variable Typing-Footnote-1395117
+Ref: Variable Typing-Footnote-2395189
+Node: Comparison Operators395266
+Ref: table-relational-ops395685
+Node: POSIX String Comparison399180
+Ref: POSIX String Comparison-Footnote-1400875
+Ref: POSIX String Comparison-Footnote-2401014
+Node: Boolean Ops401098
+Ref: Boolean Ops-Footnote-1405580
+Node: Conditional Exp405672
+Node: Function Calls407408
+Node: Precedence411285
+Node: Locales414944
+Node: Expressions Summary416576
+Node: Patterns and Actions419149
+Node: Pattern Overview420269
+Node: Regexp Patterns421946
+Node: Expression Patterns422488
+Node: Ranges426269
+Node: BEGIN/END429377
+Node: Using BEGIN/END430138
+Ref: Using BEGIN/END-Footnote-1432892
+Node: I/O And BEGIN/END432998
+Node: BEGINFILE/ENDFILE435311
+Node: Empty438542
+Node: Using Shell Variables438859
+Node: Action Overview441133
+Node: Statements443458
+Node: If Statement445306
+Node: While Statement446801
+Node: Do Statement448829
+Node: For Statement449977
+Node: Switch Statement453148
+Node: Break Statement455589
+Node: Continue Statement457681
+Node: Next Statement459508
+Node: Nextfile Statement461891
+Node: Exit Statement464580
+Node: Built-in Variables466983
+Node: User-modified468116
+Node: Auto-set475883
+Ref: Auto-set-Footnote-1492690
+Ref: Auto-set-Footnote-2492896
+Node: ARGC and ARGV492952
+Node: Pattern Action Summary497165
+Node: Arrays499595
+Node: Array Basics500924
+Node: Array Intro501768
+Ref: figure-array-elements503743
+Ref: Array Intro-Footnote-1506447
+Node: Reference to Elements506575
+Node: Assigning Elements509039
+Node: Array Example509530
+Node: Scanning an Array511289
+Node: Controlling Scanning514311
+Ref: Controlling Scanning-Footnote-1520767
+Node: Numeric Array Subscripts521083
+Node: Uninitialized Subscripts523267
+Node: Delete524886
+Ref: Delete-Footnote-1527638
+Node: Multidimensional527695
+Node: Multiscanning530790
+Node: Arrays of Arrays532381
+Node: Arrays Summary537149
+Node: Functions539242
+Node: Built-in540280
+Node: Calling Built-in541361
+Node: Numeric Functions543357
+Ref: Numeric Functions-Footnote-1547383
+Ref: Numeric Functions-Footnote-2548031
+Ref: Numeric Functions-Footnote-3548079
+Node: String Functions548351
+Ref: String Functions-Footnote-1572492
+Ref: String Functions-Footnote-2572620
+Ref: String Functions-Footnote-3572868
+Node: Gory Details572955
+Ref: table-sub-escapes574746
+Ref: table-sub-proposed576265
+Ref: table-posix-sub577628
+Ref: table-gensub-escapes579169
+Ref: Gory Details-Footnote-1579992
+Node: I/O Functions580146
+Ref: table-system-return-values586600
+Ref: I/O Functions-Footnote-1588680
+Ref: I/O Functions-Footnote-2588828
+Node: Time Functions588948
+Ref: Time Functions-Footnote-1599619
+Ref: Time Functions-Footnote-2599687
+Ref: Time Functions-Footnote-3599845
+Ref: Time Functions-Footnote-4599956
+Ref: Time Functions-Footnote-5600068
+Ref: Time Functions-Footnote-6600295
+Node: Bitwise Functions600561
+Ref: table-bitwise-ops601155
+Ref: Bitwise Functions-Footnote-1607218
+Ref: Bitwise Functions-Footnote-2607391
+Node: Type Functions607582
+Node: I18N Functions610445
+Node: User-defined612096
+Node: Definition Syntax612908
+Ref: Definition Syntax-Footnote-1618602
+Node: Function Example618673
+Ref: Function Example-Footnote-1621595
+Node: Function Calling621617
+Node: Calling A Function622205
+Node: Variable Scope623163
+Node: Pass By Value/Reference626157
+Node: Function Caveats628801
+Ref: Function Caveats-Footnote-1630848
+Node: Return Statement630968
+Node: Dynamic Typing633947
+Node: Indirect Calls634877
+Ref: Indirect Calls-Footnote-1645129
+Node: Functions Summary645257
+Node: Library Functions647962
+Ref: Library Functions-Footnote-1651569
+Ref: Library Functions-Footnote-2651712
+Node: Library Names651883
+Ref: Library Names-Footnote-1655550
+Ref: Library Names-Footnote-2655773
+Node: General Functions655859
+Node: Strtonum Function656962
+Node: Assert Function659984
+Node: Round Function663310
+Node: Cliff Random Function664850
+Node: Ordinal Functions665866
+Ref: Ordinal Functions-Footnote-1668929
+Ref: Ordinal Functions-Footnote-2669181
+Node: Join Function669391
+Ref: Join Function-Footnote-1671161
+Node: Getlocaltime Function671361
+Node: Readfile Function675103
+Node: Shell Quoting677080
+Node: Data File Management678481
+Node: Filetrans Function679113
+Node: Rewind Function683209
+Node: File Checking685118
+Ref: File Checking-Footnote-1686452
+Node: Empty Files686653
+Node: Ignoring Assigns688632
+Node: Getopt Function690182
+Ref: Getopt Function-Footnote-1705393
+Node: Passwd Functions705593
+Ref: Passwd Functions-Footnote-1714432
+Node: Group Functions714520
+Ref: Group Functions-Footnote-1722418
+Node: Walking Arrays722625
+Node: Library Functions Summary725633
+Node: Library Exercises727039
+Node: Sample Programs727504
+Node: Running Examples728274
+Node: Clones729002
+Node: Cut Program730226
+Node: Egrep Program740366
+Node: Id Program749377
+Node: Split Program759324
+Ref: Split Program-Footnote-1769214
+Node: Tee Program769387
+Node: Uniq Program772177
+Node: Wc Program779765
+Node: Bytes vs. Characters780162
+Node: Using extensions781710
+Node: wc program782464
+Node: Miscellaneous Programs787329
+Node: Dupword Program788542
+Node: Alarm Program790572
+Node: Translate Program795427
+Ref: Translate Program-Footnote-1799992
+Node: Labels Program800262
+Ref: Labels Program-Footnote-1803613
+Node: Word Sorting803697
+Node: History Sorting807769
+Node: Extract Program809994
+Node: Simple Sed818048
+Node: Igawk Program821122
+Ref: Igawk Program-Footnote-1835453
+Ref: Igawk Program-Footnote-2835655
+Ref: Igawk Program-Footnote-3835777
+Node: Anagram Program835892
+Node: Signature Program838954
+Node: Programs Summary840201
+Node: Programs Exercises841415
+Ref: Programs Exercises-Footnote-1845545
+Node: Advanced Features845631
+Node: Nondecimal Data847698
+Node: Array Sorting849289
+Node: Controlling Array Traversal849989
+Ref: Controlling Array Traversal-Footnote-1858357
+Node: Array Sorting Functions858475
+Ref: Array Sorting Functions-Footnote-1863566
+Node: Two-way I/O863762
+Ref: Two-way I/O-Footnote-1871483
+Ref: Two-way I/O-Footnote-2871670
+Node: TCP/IP Networking871752
+Node: Profiling874870
+Node: Extension Philosophy884179
+Node: Advanced Features Summary885630
+Node: Internationalization887629
+Node: I18N and L10N889109
+Node: Explaining gettext889796
+Ref: Explaining gettext-Footnote-1895688
+Ref: Explaining gettext-Footnote-2895873
+Node: Programmer i18n896038
+Ref: Programmer i18n-Footnote-1900987
+Node: Translator i18n901036
+Node: String Extraction901830
+Ref: String Extraction-Footnote-1902962
+Node: Printf Ordering903048
+Ref: Printf Ordering-Footnote-1905834
+Node: I18N Portability905898
+Ref: I18N Portability-Footnote-1908354
+Node: I18N Example908417
+Ref: I18N Example-Footnote-1911692
+Ref: I18N Example-Footnote-2911765
+Node: Gawk I18N911874
+Node: I18N Summary912523
+Node: Debugger913864
+Node: Debugging914864
+Node: Debugging Concepts915305
+Node: Debugging Terms917114
+Node: Awk Debugging919689
+Ref: Awk Debugging-Footnote-1920634
+Node: Sample Debugging Session920766
+Node: Debugger Invocation921300
+Node: Finding The Bug922686
+Node: List of Debugger Commands929160
+Node: Breakpoint Control930493
+Node: Debugger Execution Control934187
+Node: Viewing And Changing Data937549
+Node: Execution Stack941090
+Node: Debugger Info942727
+Node: Miscellaneous Debugger Commands946798
+Node: Readline Support951860
+Node: Limitations952756
+Node: Debugging Summary955310
+Node: Namespaces956589
+Node: Global Namespace957700
+Node: Qualified Names959098
+Node: Default Namespace960097
+Node: Changing The Namespace960838
+Node: Naming Rules962452
+Node: Internal Name Management964300
+Node: Namespace Example965342
+Node: Namespace And Features967904
+Node: Namespace Summary969339
+Node: Arbitrary Precision Arithmetic970816
+Node: Computer Arithmetic972303
+Ref: table-numeric-ranges976069
+Ref: table-floating-point-ranges976562
+Ref: Computer Arithmetic-Footnote-1977220
+Node: Math Definitions977277
+Ref: table-ieee-formats980253
+Node: MPFR features980820
+Node: FP Math Caution982538
+Ref: FP Math Caution-Footnote-1983610
+Node: Inexactness of computations983979
+Node: Inexact representation985010
+Node: Comparing FP Values986370
+Node: Errors accumulate987611
+Node: Strange values989067
+Ref: Strange values-Footnote-1991655
+Node: Getting Accuracy991760
+Node: Try To Round994470
+Node: Setting precision995369
+Ref: table-predefined-precision-strings996066
+Node: Setting the rounding mode997896
+Ref: table-gawk-rounding-modes998270
+Ref: Setting the rounding mode-Footnote-11002201
+Node: Arbitrary Precision Integers1002380
+Ref: Arbitrary Precision Integers-Footnote-11005555
+Node: Checking for MPFR1005704
+Node: POSIX Floating Point Problems1007178
+Ref: POSIX Floating Point Problems-Footnote-11011463
+Node: Floating point summary1011501
+Node: Dynamic Extensions1013691
+Node: Extension Intro1015244
+Node: Plugin License1016510
+Node: Extension Mechanism Outline1017307
+Ref: figure-load-extension1017746
+Ref: figure-register-new-function1019311
+Ref: figure-call-new-function1020403
+Node: Extension API Description1022465
+Node: Extension API Functions Introduction1024178
+Ref: table-api-std-headers1026014
+Node: General Data Types1030263
+Ref: General Data Types-Footnote-11038893
+Node: Memory Allocation Functions1039192
+Ref: Memory Allocation Functions-Footnote-11043693
+Node: Constructor Functions1043792
+Node: API Ownership of MPFR and GMP Values1047258
+Node: Registration Functions1048571
+Node: Extension Functions1049271
+Node: Exit Callback Functions1054593
+Node: Extension Version String1055843
+Node: Input Parsers1056506
+Node: Output Wrappers1069227
+Node: Two-way processors1073739
+Node: Printing Messages1076004
+Ref: Printing Messages-Footnote-11077175
+Node: Updating ERRNO1077328
+Node: Requesting Values1078067
+Ref: table-value-types-returned1078804
+Node: Accessing Parameters1079740
+Node: Symbol Table Access1080977
+Node: Symbol table by name1081489
+Ref: Symbol table by name-Footnote-11084513
+Node: Symbol table by cookie1084641
+Ref: Symbol table by cookie-Footnote-11088826
+Node: Cached values1088890
+Ref: Cached values-Footnote-11092426
+Node: Array Manipulation1092579
+Ref: Array Manipulation-Footnote-11093670
+Node: Array Data Types1093707
+Ref: Array Data Types-Footnote-11096365
+Node: Array Functions1096457
+Node: Flattening Arrays1100955
+Node: Creating Arrays1107931
+Node: Redirection API1112698
+Node: Extension API Variables1115531
+Node: Extension Versioning1116242
+Ref: gawk-api-version1116671
+Node: Extension GMP/MPFR Versioning1118402
+Node: Extension API Informational Variables1120030
+Node: Extension API Boilerplate1121103
+Node: Changes from API V11125077
+Node: Finding Extensions1126649
+Node: Extension Example1127208
+Node: Internal File Description1128006
+Node: Internal File Ops1132086
+Ref: Internal File Ops-Footnote-11143436
+Node: Using Internal File Ops1143576
+Ref: Using Internal File Ops-Footnote-11145959
+Node: Extension Samples1146233
+Node: Extension Sample File Functions1147762
+Node: Extension Sample Fnmatch1155411
+Node: Extension Sample Fork1156898
+Node: Extension Sample Inplace1158116
+Node: Extension Sample Ord1161742
+Node: Extension Sample Readdir1162578
+Ref: table-readdir-file-types1163467
+Node: Extension Sample Revout1164534
+Node: Extension Sample Rev2way1165123
+Node: Extension Sample Read write array1165863
+Node: Extension Sample Readfile1167805
+Node: Extension Sample Time1168900
+Node: Extension Sample API Tests1170652
+Node: gawkextlib1171144
+Node: Extension summary1174062
+Node: Extension Exercises1177764
+Node: Language History1179006
+Node: V7/SVR3.11180662
+Node: SVR41182814
+Node: POSIX1184248
+Node: BTL1185629
+Node: POSIX/GNU1186358
+Node: Feature History1192136
+Node: Common Extensions1208455
+Node: Ranges and Locales1209738
+Ref: Ranges and Locales-Footnote-11214354
+Ref: Ranges and Locales-Footnote-21214381
+Ref: Ranges and Locales-Footnote-31214616
+Node: Contributors1214839
+Node: History summary1220836
+Node: Installation1222216
+Node: Gawk Distribution1223160
+Node: Getting1223644
+Node: Extracting1224607
+Node: Distribution contents1226245
+Node: Unix Installation1232725
+Node: Quick Installation1233407
+Node: Shell Startup Files1235821
+Node: Additional Configuration Options1236910
+Node: Configuration Philosophy1239225
+Node: Non-Unix Installation1241594
+Node: PC Installation1242054
+Node: PC Binary Installation1242892
+Node: PC Compiling1243327
+Node: PC Using1244444
+Node: Cygwin1247997
+Node: MSYS1249221
+Node: VMS Installation1249823
+Node: VMS Compilation1250614
+Ref: VMS Compilation-Footnote-11251843
+Node: VMS Dynamic Extensions1251901
+Node: VMS Installation Details1253586
+Node: VMS Running1255839
+Node: VMS GNV1260118
+Node: VMS Old Gawk1260853
+Node: Bugs1261324
+Node: Bug address1261987
+Node: Usenet1264969
+Node: Maintainers1265973
+Node: Other Versions1267158
+Node: Installation summary1274246
+Node: Notes1275455
+Node: Compatibility Mode1276249
+Node: Additions1277031
+Node: Accessing The Source1277956
+Node: Adding Code1279393
+Node: New Ports1285612
+Node: Derived Files1289987
+Ref: Derived Files-Footnote-11295647
+Ref: Derived Files-Footnote-21295682
+Ref: Derived Files-Footnote-31296280
+Node: Future Extensions1296394
+Node: Implementation Limitations1297052
+Node: Extension Design1298262
+Node: Old Extension Problems1299406
+Ref: Old Extension Problems-Footnote-11300924
+Node: Extension New Mechanism Goals1300981
+Ref: Extension New Mechanism Goals-Footnote-11304345
+Node: Extension Other Design Decisions1304534
+Node: Extension Future Growth1306647
+Node: Notes summary1307253
+Node: Basic Concepts1308411
+Node: Basic High Level1309092
+Ref: figure-general-flow1309374
+Ref: figure-process-flow1310059
+Ref: Basic High Level-Footnote-11313360
+Node: Basic Data Typing1313545
+Node: Glossary1316873
+Node: Copying1348758
+Node: GNU Free Documentation License1386301
+Node: Index1411421

End Tag Table
diff --git a/doc/gawk.texi b/doc/gawk.texi
index 414d5d8c..078a0ec8 100644
--- a/doc/gawk.texi
+++ b/doc/gawk.texi
@@ -920,6 +920,7 @@ particular records in a file and perform operations upon them.
* Inexact representation:: Numbers are not exactly represented.
* Comparing FP Values:: How to compare floating point values.
* Errors accumulate:: Errors get bigger as they go.
+* Strange values:: A few words about infinities and NaNs.
* Getting Accuracy:: Getting more accuracy takes some work.
* Try To Round:: Add digits and round.
* Setting precision:: How to set the precision.
@@ -3136,11 +3137,12 @@ column means that the person is a friend.
An @samp{R} means that the person is a relative:
@example
-@c system if test ! -d eg ; then mkdir eg ; fi
-@c system if test ! -d eg/lib ; then mkdir eg/lib ; fi
-@c system if test ! -d eg/data ; then mkdir eg/data ; fi
-@c system if test ! -d eg/prog ; then mkdir eg/prog ; fi
-@c system if test ! -d eg/misc ; then mkdir eg/misc ; fi
+@c system if test ! -d eg ; then mkdir eg ; fi
+@c system if test ! -d eg/lib ; then mkdir eg/lib ; fi
+@c system if test ! -d eg/data ; then mkdir eg/data ; fi
+@c system if test ! -d eg/prog ; then mkdir eg/prog ; fi
+@c system if test ! -d eg/misc ; then mkdir eg/misc ; fi
+@c system if test ! -d eg/test-programs ; then mkdir eg/test-programs ; fi
@c file eg/data/mail-list
Amelia 555-5553 amelia.zodiacusque@@gmail.com F
Anthony 555-3412 anthony.asserturo@@hotmail.com A
@@ -8442,7 +8444,7 @@ FPAT = "([^,]*)|(\"[^\"]+\")"
@c Per email from Ed Morton <mortoneccc@comcast.net>
@c
@c WONTFIX: 10/2020
-@c This is too much work. FPAT and CSV files are very flakey and
+@c This is too much work. FPAT and CSV files are very flaky and
@c fragile. Doing something like this is merely inviting trouble.
As with @code{FS}, the @code{IGNORECASE} variable (@pxref{User-modified})
@@ -10101,7 +10103,7 @@ infinity are formatted as
and positive infinity as
@samp{inf} or @samp{infinity}.
The special ``not a number'' value formats as @samp{-nan} or @samp{nan}
-(@pxref{Math Definitions}).
+(@pxref{Strange values}).
@item @code{%F}
Like @samp{%f}, but the infinity and ``not a number'' values are spelled
@@ -18337,7 +18339,7 @@ compatibility mode (@pxref{Options}).
@cindexawkfunc{log}
@cindex logarithm
Return the natural logarithm of @var{x}, if @var{x} is positive;
-otherwise, return @code{NaN} (``not a number'') on IEEE 754 systems.
+otherwise, return NaN (``not a number'') on IEEE 754 systems.
Additionally, @command{gawk} prints a warning message when @code{x}
is negative.
@@ -33684,21 +33686,9 @@ A special value representing infinity. Operations involving another
number and infinity produce infinity.
@item NaN
-``Not a number.''@footnote{Thanks to Michael Brennan for this description,
-which we have paraphrased, and for the examples.} A special value that
-results from attempting a calculation that has no answer as a real number.
-In such a case, programs can either receive a floating-point exception,
-or get @code{NaN} back as the result. The IEEE 754 standard recommends
-that systems return @code{NaN}. Some examples:
-
-@table @code
-@item sqrt(-1)
-This makes sense in the range of complex numbers, but not in the
-range of real numbers, so the result is @code{NaN}.
-
-@item log(-8)
-@minus{}8 is out of the domain of @code{log()}, so the result is @code{NaN}.
-@end table
+``Not a number.'' A special value that results from attempting a
+calculation that has no answer as a real number. @xref{Strange values},
+for more information about infinity and not-a-number values.
@item Normalized
How the significand (see later in this list) is usually stored. The
@@ -33867,6 +33857,7 @@ decimal places in the final result.
* Inexact representation:: Numbers are not exactly represented.
* Comparing FP Values:: How to compare floating point values.
* Errors accumulate:: Errors get bigger as they go.
+* Strange values:: A few words about infinities and NaNs.
@end menu
@node Inexact representation
@@ -33988,6 +33979,242 @@ $ @kbd{gawk 'BEGIN @{}
@print{} 4
@end example
+@node Strange values
+@subsubsection Floating Point Values They Didn't Talk About In School
+
+Both IEEE 754 floating-point hardware, and MPFR, support two kinds of
+values that you probably didn't learn about in school. The first is
+@dfn{infinity}, a special value, that can be either negative or positive,
+and which is either smaller than any other value (negative infinity),
+or larger than any other value (positive infinity). When such values
+are generated, @command{gawk} prints them as either @samp{-inf} or
+@samp{+inf}, respectively. It accepts those strings as data input and
+converts them to the proper floating-point values internally.
+
+Infinity values of the same sign compare as equal to each other.
+Otherwise, operations (addition, subtraction, etc.) involving another
+number and infinity produce mathematically reasonable results.
+
+The second kind of value is ``not a number'', or NaN for
+short.@footnote{Thanks to Michael Brennan for this description, which we
+have paraphrased, and for the examples.} This is a special value that results
+from attempting a calculation that has no answer as a real number.
+In such a case, programs can either receive a floating-point exception,
+or get NaN back as the result. The IEEE 754 standard recommends
+that systems return NaN. Some examples:
+
+@table @code
+@item sqrt(-1)
+@iftex
+The @math{\sqrt{-1}}
+@end iftex
+@ifnottex
+This
+@end ifnottex
+makes sense in the range of complex numbers, but not in the
+range of real numbers, so the result is NaN.
+
+@item log(-8)
+@minus{}8 is out of the domain of @code{log()}, so the result is NaN.
+@end table
+
+NaN values are strange. In particular, they cannot be compared with other
+floating point values; any such comparison, except for ``is not equal
+to'', returns false. NaN values are so much unequal to other values that
+even comparing two identical NaN values with @code{!=} returns true!
+
+NaN values can also be signed, although it depends upon the implementation
+as to which sign you get for any operation that returns a NaN. For
+example, on some systems, @code{sqrt(-1)} returns a negative NaN. On
+others, it returns a positive NaN.
+
+When such values are generated, @command{gawk} prints them as either
+@samp{-nan} or @samp{+nan}, respectively. Here too, @command{gawk}
+accepts those strings as data input and converts them to the proper
+floating-point values internally.
+
+If you want to dive more deeply into this topic, you can find
+test programs in C, @command{awk} and Python in the directory
+@file{awklib/eg/test-programs} in the @command{gawk} distribution.
+These programs enable comparison among programming languages as to how
+they handle NaN and infinity values.
+
+@ignore
+@c file eg/test-programs/gen-float-table.awk
+function eq(left, right)
+{
+ return left == right
+}
+
+function ne(left, right)
+{
+ return left != right
+}
+
+function lt(left, right)
+{
+ return left < right
+}
+
+function le(left, right)
+{
+ return left <= right
+}
+
+function gt(left, right)
+{
+ return left > right
+}
+
+function ge(left, right)
+{
+ return left >= right
+}
+
+BEGIN {
+ nan = sqrt(-1)
+ inf = -log(0)
+ split("== != < <= > >=", names)
+ names[3] = names[3] " "
+ names[5] = names[5] " "
+ split("eq ne lt le gt ge", funcs)
+
+ compare[1] = 2.0
+ compare[2] = values[1] = -sqrt(-1.0) # nan
+ compare[3] = values[2] = sqrt(-1.0) # -nan
+ compare[4] = values[3] = -log(0.0) # inf
+ compare[5] = values[4] = log(0.0) # -inf
+
+ for (i = 1; i in values; i++) {
+ for (j = 1; j in compare; j++) {
+ for (k = 1; k in names; k++) {
+ the_func = funcs[k]
+ printf("%g %s %g -> %s\n",
+ values[i],
+ names[k],
+ compare[j],
+ @the_func(values[i], compare[j]) ?
+ "true" : "false");
+ }
+ printf("\n");
+ }
+ }
+}
+@c endfile
+@end ignore
+
+@ignore
+@c file eg/test-programs/gen-float-table.c
+#include <stdio.h>
+#include <math.h>
+#include <stdbool.h>
+
+#define def_func(name, op) \
+ bool name(double left, double right) { \
+ return left op right; \
+ }
+
+def_func(eq, ==)
+def_func(ne, !=)
+def_func(lt, <)
+def_func(le, <=)
+def_func(gt, >)
+def_func(ge, >=)
+
+struct {
+ const char *name;
+ bool (*func)(double left, double right);
+} functions[] = {
+ { "==", eq },
+ { "!=", ne },
+ { "< ", lt },
+ { "<=", le },
+ { "> ", gt },
+ { ">=", ge },
+ { 0, 0 }
+};
+
+int main()
+{
+ double values[] = {
+ -sqrt(-1), // nan
+ sqrt(-1), // -nan
+ -log(0.0), // inf
+ log(0.0) // -inf
+ };
+ double compare[] = { 2.0,
+ -sqrt(-1), // nan
+ sqrt(-1), // -nan
+ -log(0.0), // inf
+ log(0.0) // -inf
+ };
+
+ int i, j, k;
+
+ for (i = 0; i < 4; i++) {
+ for (j = 0; j < 5; j++) {
+ for (k = 0; functions[k].name != NULL; k++) {
+ printf("%g %s %g -> %s\n", values[i],
+ functions[k].name,
+ compare[j],
+ functions[k].func(values[i], compare[j]) ? "true" : "false");
+ }
+ printf("\n");
+ }
+ }
+
+ return 0;
+}
+@c endfile
+@end ignore
+
+@ignore
+@c file eg/test-programs/gen-float-table.py
+from math import *
+
+nan = float('NaN')
+inf = float('Inf')
+
+def eq(left, right):
+ return left == right
+
+def ne(left, right):
+ return left != right
+
+def lt(left, right):
+ return left < right
+
+def le(left, right):
+ return left <= right
+
+def gt(left, right):
+ return left > right
+
+def ge(left, right):
+ return left >= right
+
+func_map = {
+ "==": eq,
+ "!=": ne,
+ "< ": lt,
+ "<=": le,
+ "> ": gt,
+ ">=": ge,
+}
+
+compare = [2.0, nan, -nan, inf, -inf]
+values = [nan, -nan, inf, -inf]
+
+for i in range(len(values)):
+ for j in range(len(compare)):
+ for op in func_map:
+ print("%g %s %g -> %s" %
+ (values[i], op, compare[j], func_map[op](values[i], compare[j])))
+
+ print("")
+@c endfile
+@end ignore
+
@node Getting Accuracy
@subsection Getting the Accuracy You Need
diff --git a/doc/gawktexi.in b/doc/gawktexi.in
index 3f4ec89d..78ad076d 100644
--- a/doc/gawktexi.in
+++ b/doc/gawktexi.in
@@ -915,6 +915,7 @@ particular records in a file and perform operations upon them.
* Inexact representation:: Numbers are not exactly represented.
* Comparing FP Values:: How to compare floating point values.
* Errors accumulate:: Errors get bigger as they go.
+* Strange values:: A few words about infinities and NaNs.
* Getting Accuracy:: Getting more accuracy takes some work.
* Try To Round:: Add digits and round.
* Setting precision:: How to set the precision.
@@ -3046,11 +3047,12 @@ column means that the person is a friend.
An @samp{R} means that the person is a relative:
@example
-@c system if test ! -d eg ; then mkdir eg ; fi
-@c system if test ! -d eg/lib ; then mkdir eg/lib ; fi
-@c system if test ! -d eg/data ; then mkdir eg/data ; fi
-@c system if test ! -d eg/prog ; then mkdir eg/prog ; fi
-@c system if test ! -d eg/misc ; then mkdir eg/misc ; fi
+@c system if test ! -d eg ; then mkdir eg ; fi
+@c system if test ! -d eg/lib ; then mkdir eg/lib ; fi
+@c system if test ! -d eg/data ; then mkdir eg/data ; fi
+@c system if test ! -d eg/prog ; then mkdir eg/prog ; fi
+@c system if test ! -d eg/misc ; then mkdir eg/misc ; fi
+@c system if test ! -d eg/test-programs ; then mkdir eg/test-programs ; fi
@c file eg/data/mail-list
Amelia 555-5553 amelia.zodiacusque@@gmail.com F
Anthony 555-3412 anthony.asserturo@@hotmail.com A
@@ -7965,7 +7967,7 @@ FPAT = "([^,]*)|(\"[^\"]+\")"
@c Per email from Ed Morton <mortoneccc@comcast.net>
@c
@c WONTFIX: 10/2020
-@c This is too much work. FPAT and CSV files are very flakey and
+@c This is too much work. FPAT and CSV files are very flaky and
@c fragile. Doing something like this is merely inviting trouble.
As with @code{FS}, the @code{IGNORECASE} variable (@pxref{User-modified})
@@ -9624,7 +9626,7 @@ infinity are formatted as
and positive infinity as
@samp{inf} or @samp{infinity}.
The special ``not a number'' value formats as @samp{-nan} or @samp{nan}
-(@pxref{Math Definitions}).
+(@pxref{Strange values}).
@item @code{%F}
Like @samp{%f}, but the infinity and ``not a number'' values are spelled
@@ -17532,7 +17534,7 @@ compatibility mode (@pxref{Options}).
@cindexawkfunc{log}
@cindex logarithm
Return the natural logarithm of @var{x}, if @var{x} is positive;
-otherwise, return @code{NaN} (``not a number'') on IEEE 754 systems.
+otherwise, return NaN (``not a number'') on IEEE 754 systems.
Additionally, @command{gawk} prints a warning message when @code{x}
is negative.
@@ -32620,21 +32622,9 @@ A special value representing infinity. Operations involving another
number and infinity produce infinity.
@item NaN
-``Not a number.''@footnote{Thanks to Michael Brennan for this description,
-which we have paraphrased, and for the examples.} A special value that
-results from attempting a calculation that has no answer as a real number.
-In such a case, programs can either receive a floating-point exception,
-or get @code{NaN} back as the result. The IEEE 754 standard recommends
-that systems return @code{NaN}. Some examples:
-
-@table @code
-@item sqrt(-1)
-This makes sense in the range of complex numbers, but not in the
-range of real numbers, so the result is @code{NaN}.
-
-@item log(-8)
-@minus{}8 is out of the domain of @code{log()}, so the result is @code{NaN}.
-@end table
+``Not a number.'' A special value that results from attempting a
+calculation that has no answer as a real number. @xref{Strange values},
+for more information about infinity and not-a-number values.
@item Normalized
How the significand (see later in this list) is usually stored. The
@@ -32803,6 +32793,7 @@ decimal places in the final result.
* Inexact representation:: Numbers are not exactly represented.
* Comparing FP Values:: How to compare floating point values.
* Errors accumulate:: Errors get bigger as they go.
+* Strange values:: A few words about infinities and NaNs.
@end menu
@node Inexact representation
@@ -32924,6 +32915,242 @@ $ @kbd{gawk 'BEGIN @{}
@print{} 4
@end example
+@node Strange values
+@subsubsection Floating Point Values They Didn't Talk About In School
+
+Both IEEE 754 floating-point hardware, and MPFR, support two kinds of
+values that you probably didn't learn about in school. The first is
+@dfn{infinity}, a special value, that can be either negative or positive,
+and which is either smaller than any other value (negative infinity),
+or larger than any other value (positive infinity). When such values
+are generated, @command{gawk} prints them as either @samp{-inf} or
+@samp{+inf}, respectively. It accepts those strings as data input and
+converts them to the proper floating-point values internally.
+
+Infinity values of the same sign compare as equal to each other.
+Otherwise, operations (addition, subtraction, etc.) involving another
+number and infinity produce mathematically reasonable results.
+
+The second kind of value is ``not a number'', or NaN for
+short.@footnote{Thanks to Michael Brennan for this description, which we
+have paraphrased, and for the examples.} This is a special value that results
+from attempting a calculation that has no answer as a real number.
+In such a case, programs can either receive a floating-point exception,
+or get NaN back as the result. The IEEE 754 standard recommends
+that systems return NaN. Some examples:
+
+@table @code
+@item sqrt(-1)
+@iftex
+The @math{\sqrt{-1}}
+@end iftex
+@ifnottex
+This
+@end ifnottex
+makes sense in the range of complex numbers, but not in the
+range of real numbers, so the result is NaN.
+
+@item log(-8)
+@minus{}8 is out of the domain of @code{log()}, so the result is NaN.
+@end table
+
+NaN values are strange. In particular, they cannot be compared with other
+floating point values; any such comparison, except for ``is not equal
+to'', returns false. NaN values are so much unequal to other values that
+even comparing two identical NaN values with @code{!=} returns true!
+
+NaN values can also be signed, although it depends upon the implementation
+as to which sign you get for any operation that returns a NaN. For
+example, on some systems, @code{sqrt(-1)} returns a negative NaN. On
+others, it returns a positive NaN.
+
+When such values are generated, @command{gawk} prints them as either
+@samp{-nan} or @samp{+nan}, respectively. Here too, @command{gawk}
+accepts those strings as data input and converts them to the proper
+floating-point values internally.
+
+If you want to dive more deeply into this topic, you can find
+test programs in C, @command{awk} and Python in the directory
+@file{awklib/eg/test-programs} in the @command{gawk} distribution.
+These programs enable comparison among programming languages as to how
+they handle NaN and infinity values.
+
+@ignore
+@c file eg/test-programs/gen-float-table.awk
+function eq(left, right)
+{
+ return left == right
+}
+
+function ne(left, right)
+{
+ return left != right
+}
+
+function lt(left, right)
+{
+ return left < right
+}
+
+function le(left, right)
+{
+ return left <= right
+}
+
+function gt(left, right)
+{
+ return left > right
+}
+
+function ge(left, right)
+{
+ return left >= right
+}
+
+BEGIN {
+ nan = sqrt(-1)
+ inf = -log(0)
+ split("== != < <= > >=", names)
+ names[3] = names[3] " "
+ names[5] = names[5] " "
+ split("eq ne lt le gt ge", funcs)
+
+ compare[1] = 2.0
+ compare[2] = values[1] = -sqrt(-1.0) # nan
+ compare[3] = values[2] = sqrt(-1.0) # -nan
+ compare[4] = values[3] = -log(0.0) # inf
+ compare[5] = values[4] = log(0.0) # -inf
+
+ for (i = 1; i in values; i++) {
+ for (j = 1; j in compare; j++) {
+ for (k = 1; k in names; k++) {
+ the_func = funcs[k]
+ printf("%g %s %g -> %s\n",
+ values[i],
+ names[k],
+ compare[j],
+ @the_func(values[i], compare[j]) ?
+ "true" : "false");
+ }
+ printf("\n");
+ }
+ }
+}
+@c endfile
+@end ignore
+
+@ignore
+@c file eg/test-programs/gen-float-table.c
+#include <stdio.h>
+#include <math.h>
+#include <stdbool.h>
+
+#define def_func(name, op) \
+ bool name(double left, double right) { \
+ return left op right; \
+ }
+
+def_func(eq, ==)
+def_func(ne, !=)
+def_func(lt, <)
+def_func(le, <=)
+def_func(gt, >)
+def_func(ge, >=)
+
+struct {
+ const char *name;
+ bool (*func)(double left, double right);
+} functions[] = {
+ { "==", eq },
+ { "!=", ne },
+ { "< ", lt },
+ { "<=", le },
+ { "> ", gt },
+ { ">=", ge },
+ { 0, 0 }
+};
+
+int main()
+{
+ double values[] = {
+ -sqrt(-1), // nan
+ sqrt(-1), // -nan
+ -log(0.0), // inf
+ log(0.0) // -inf
+ };
+ double compare[] = { 2.0,
+ -sqrt(-1), // nan
+ sqrt(-1), // -nan
+ -log(0.0), // inf
+ log(0.0) // -inf
+ };
+
+ int i, j, k;
+
+ for (i = 0; i < 4; i++) {
+ for (j = 0; j < 5; j++) {
+ for (k = 0; functions[k].name != NULL; k++) {
+ printf("%g %s %g -> %s\n", values[i],
+ functions[k].name,
+ compare[j],
+ functions[k].func(values[i], compare[j]) ? "true" : "false");
+ }
+ printf("\n");
+ }
+ }
+
+ return 0;
+}
+@c endfile
+@end ignore
+
+@ignore
+@c file eg/test-programs/gen-float-table.py
+from math import *
+
+nan = float('NaN')
+inf = float('Inf')
+
+def eq(left, right):
+ return left == right
+
+def ne(left, right):
+ return left != right
+
+def lt(left, right):
+ return left < right
+
+def le(left, right):
+ return left <= right
+
+def gt(left, right):
+ return left > right
+
+def ge(left, right):
+ return left >= right
+
+func_map = {
+ "==": eq,
+ "!=": ne,
+ "< ": lt,
+ "<=": le,
+ "> ": gt,
+ ">=": ge,
+}
+
+compare = [2.0, nan, -nan, inf, -inf]
+values = [nan, -nan, inf, -inf]
+
+for i in range(len(values)):
+ for j in range(len(compare)):
+ for op in func_map:
+ print("%g %s %g -> %s" %
+ (values[i], op, compare[j], func_map[op](values[i], compare[j])))
+
+ print("")
+@c endfile
+@end ignore
+
@node Getting Accuracy
@subsection Getting the Accuracy You Need
diff --git a/doc/it/ChangeLog b/doc/it/ChangeLog
index 863eef47..5a6bd03d 100644
--- a/doc/it/ChangeLog
+++ b/doc/it/ChangeLog
@@ -1,3 +1,7 @@
+2020-11-20 Antonio Giovanni Colombo <azc100@gmail.com>
+
+ * gawktexi.in: Updated.
+
2020-11-01 Antonio Giovanni Colombo <azc100@gmail.com>
* texinfo.tex: Updated.
diff --git a/doc/it/gawktexi.in b/doc/it/gawktexi.in
index fe7c6b29..a8c0874f 100644..100755
--- a/doc/it/gawktexi.in
+++ b/doc/it/gawktexi.in
@@ -1065,13 +1065,14 @@ Copyright dell'edizione italiana @copyright{} 2016 -- Free Software Foundation,
esattamente.
* Confronti tra valori in VM:: Come confrontare valori in virgola mobile.
* Gli errori si sommano:: Gli errori diventano sempre maggiori.
+* Valori strani:: Un cenno riguardo ai valori infiniti e a NaN [``non @`e un numero''].
* Ottenere la precisione:: Ottenere la precisione voluta.
* Tentare di arrotondare:: Tentare di aggiungere bit di precisione e
arrotondare.
* Impostare la precisione:: Impostare la precisione.
* Impostare modo di arrotondare:: Impostare la modalit@`a di
arrotondamento.
-* Controllare disponibilit@`a MPFR:: Come controllare se MPFR @`e disponibile.
+* Controllare disponibilit@`a MPFR:: Come controllare se MPFR @`e disponibile.
* Interi a precisione arbitraria:: Aritmetica dei numeri interi a precisione
arbitraria con @command{gawk}.
* Problemi virgola mobile POSIX:: Confronto tra standard e uso corrente.
@@ -3338,11 +3339,12 @@ persona @`e un amico [Friend]. Una @samp{R} vuol dire che quella persona @`e
un parente [Relative]:
@example
-@c system if test ! -d eg ; then mkdir eg ; fi
-@c system if test ! -d eg/lib ; then mkdir eg/lib ; fi
-@c system if test ! -d eg/data ; then mkdir eg/data ; fi
-@c system if test ! -d eg/prog ; then mkdir eg/prog ; fi
-@c system if test ! -d eg/misc ; then mkdir eg/misc ; fi
+@c system if test ! -d eg ; then mkdir eg ; fi
+@c system if test ! -d eg/lib ; then mkdir eg/lib ; fi
+@c system if test ! -d eg/data ; then mkdir eg/data ; fi
+@c system if test ! -d eg/prog ; then mkdir eg/prog ; fi
+@c system if test ! -d eg/misc ; then mkdir eg/misc ; fi
+@c system if test ! -d eg/test-programs ; then mkdir eg/test-programs ; fi
@c file eg/data/mail-list
Amelia 555-5553 amelia.zodiacusque@@gmail.com F
Anthony 555-3412 anthony.asserturo@@hotmail.com A
@@ -8710,7 +8712,7 @@ FPAT = "([^,]*)|(\"[^\"]+\")"
@c Per email from Ed Morton <mortoneccc@comcast.net>
@c
@c WONTFIX: 10/2020
-@c This is too much work. FPAT and CSV files are very flakey and
+@c This is too much work. FPAT and CSV files are very flaky and
@c fragile. Doing something like this is merely inviting trouble.
Come per @code{FS}, la variabile @code{IGNORECASE}
@@ -10473,9 +10475,9 @@ dallo standard IEEE 754, il valore infinito negativo @`e rappresentato come
@samp{-inf} o @samp{-infinity},
e l'infinito positivo come
@samp{inf} o @samp{infinity}.
-Il valore speciale ``not a number'' [non @`e un numero] viene scritto come
+Il valore speciale ``not a number'' ["non @`e un numero"] viene scritto come
@samp{-nan} o @samp{nan}
-(@pxref{Definizioni matematiche}).
+(@pxref{Valori strani}).
@item @code{%F}
Come @samp{%f}, ma i valori di infinito e di ``not a number'' sono scritti
@@ -16060,16 +16062,17 @@ risultato.
In @command{gawk}, l'esecuzione di @code{nextfile} produce ulteriori effetti:
le eventuali regole @code{ENDFILE}
sono eseguite se @command{gawk} non
-si trova correntemente all'interno di una regola @code{END} o
-@code{BEGINFILE}; @code{ARGIND} @`e
+si trova correntemente all'interno di una regola @code{END},
+@code{ARGIND} @`e
incrementato e le eventuali regole @code{BEGINFILE} sono eseguite.
(@code{ARGIND} non @`e stato ancora trattato.
@xref{Variabili predefinite}.)
-In @command{gawk}, @code{nextfile} @`e utile all'interno di una regola
+C'@`e un ulteriore caso speciale di utilizzo in @command{gawk}.
+@code{nextfile} @`e utile all'interno di una regola
@code{BEGINFILE} per evitare di elaborare un file che altrimenti causerebbe
un errore fatale in @command{gawk}.
-In questo caso, le regole @code{ENDFILE} non vengono eseguite.
+In questo caso speciale, le regole @code{ENDFILE} non vengono eseguite.
@xref{BEGINFILE/ENDFILE}.
Sebbene possa sembrare che @samp{close(FILENAME)} ottenga lo stesso
@@ -19051,8 +19054,8 @@ modalit@`a compatibile (@pxref{Opzioni}).
@cindexawkfunc{log}
@cindex logaritmo
Restituisce il logaritmo naturale di @var{x}, se @var{x} @`e positivo;
-altrimenti, restituisce @code{NaN} (``not a number'') sui sistemi che
-implementano lo standard IEEE 754.
+altrimenti, restituisce NaN (``not a number'',[``non @`e un numero''])
+sui sistemi che implementano lo standard IEEE 754.
Inoltre, @command{gawk} stampa un messaggio di avvertimento qualora @code{x}
sia negativo.
@@ -35366,23 +35369,10 @@ Come i numeri vanno arrotondati, per eccesso o per difetto, quando necessario.
Maggiori dettagli verranno forniti in seguito.
@item NaN
-``Not a number'' (Non un Numero).@footnote{Grazie a Michael
-Brennan per questa descrizione, che abbiamo parafrasato, e per gli esempi.} Un
-valore speciale che risulta da un calcolo che non ha risposta come numero
-reale. In tal caso, i programmi possono o ricevere un'eccezione di virgola
-mobile, o restituire @code{NaN} come risultato. Lo standard IEEE 754
-consiglia che i sistemi restituiscano @code{NaN}. Alcuni esempi:
-
-@table @code
-@item sqrt(-1)
-La radice quadrata di @minus{}1 ha senso nell'insieme dei numeri complessi,
-ma non nell'insieme dei numeri reali,
-per cui il risultato @`e @code{NaN}.
-
-@item log(-8)
-Il logaritmo di @minus{}8 @`e fuori dal dominio di @code{log()},
-per cui il risultato @`e @code{NaN}.
-@end table
+``Not a number'' (``non @`e un numero''). Un valore speciale
+che risulta da un calcolo che non ha come risposta un numero
+reale. @xref{Valori strani}, per maggiori informazioni riguardo
+ai valori infiniti e ai valori ``non-un-numero''.
@item Normalizzato (formato)
Come la mantissa (vedi oltre in questa lista) @`e usualmente memorizzata. Il
@@ -35534,8 +35524,7 @@ ottenere ulteriori informazioni, e non basarsi solo su quanto qui detto.
* Ottenere la precisione:: Ottenere pi@`u precisione richiede qualche
sforzo.
* Tentare di arrotondare:: Aggiungere cifre di precisione e arrotondare.
-* Impostare la precisione:: Come impostare la precisione.
-* Impostare modo di arrotondare:: Impostare le modalit@`a di arrotondamento.
+* Valori strani:: Un cenno riguardo ai valori infiniti e a NaN [``non @`e un numero''].
@end menu
@node Inesattezza nei calcoli
@@ -35682,6 +35671,257 @@ $ @kbd{gawk 'BEGIN @{}
@print{} 4
@end example
+@node Valori strani
+@subsubsection Valori in virgola mobile non spiegati a scuola
+
+Sia l'hardware che implementa lo standard per i numeri in virgola
+mobili IEEE 754, che la libreria matematica MPFR, prevedono due
+tipi di valori di cui probabilmente non vi hanno parlato a scuola.
+Il primo @`e il valore @dfn{infinity} (``infinito''), un valore speciale
+che pu@`o avere un segno sia negativo che positivo, e che @`e pi@`u
+piccolo di ogni altro valore (infinito negativo), o maggiore di ogni
+altro valore (infinito positivo). Quando vengono generati tali valori
+@command{gawk} li stampa come @samp{-inf} o @samp{+inf}, rispettivamente.
+@command{gawk} accetta queste stringhe come dati in input, e li converte
+internamente all'appropriato valore in virgola mobile.
+
+Valori di infinito che abbiano lo stesso segno risultano uguali
+quando sono confrontati fra loro.
+Per il resto, altre operazioni (addizione, sottrazione, etc.)
+che hanno come operando un infinito e un altro numero producono
+risultati matematicamente ragionevoli.
+
+Il secondo tipo di valore @`e ``not a number'' [``non @`e un numero'']
+scritto in forma abbreviata come NaN.@footnote{Grazie a Michael Brennan
+per questa descrizione, che abbiamo parafrasato, e per gli esempi.}
+
+Questo @`e un valore speciale che risulta da un calcolo che non ha come
+risposta un numero reale. In tal caso, i programmi possono o ricevere
+un’eccezione di virgola mobile, o restituire NaN come risultato.
+Lo standard IEEE 754 consiglia che i sistemi restituiscano NaN.
+Alcuni esempi:
+
+@table @code
+@item sqrt(-1)
+@iftex
+La funzione @math{\sqrt{-1}}
+@end iftex
+@ifnottex
+Questa funzione
+@end ifnottex
+ha senso nell'insieme dei numeri complessi,
+ma non nell'insieme dei numeri reali,
+per cui il risultato @`e @code{NaN}.
+
+@item log(-8)
+Il logaritmo di @minus{}8 @`e fuori dal dominio di @code{log()},
+per cui il risultato @`e @code{NaN}.
+@end table
+
+I valori Nan sono strani. In particolare, non possono essere confrontati
+con altri numeri in virgola mobile; ogni confronto di questo tipo, eccetto
+quello ``non uguale a'', restituisce il valore ``falso''.
+I valori NaN sono talmente differenti da altri valori che perfino il
+confronto di due valori NaN identici fra loro con @code{!=} restituisce
+il valore ``vero''!
+
+I valori NaN possono anche avere un segno (positivo o negativo),
+anche se dipende dall'implementazione quale segno viene restituito
+da qualsiasi operazione il cui risultato sia un valore NaN.
+Per esempio, su alcuni sistemi la funzione @code{sqrt(-1)}
+restituisce un NaN negativo. Su altri sistemi il NaN restituito
+@`e invece positivo.
+
+Quando tali valori vengono generati, @command{gawk} li stampa
+come @samp{-nan} o @samp{+nan}, rispettivamente. Anche per
+questi valori, @command{gawk} accetta queste stringhe come
+dati in input e le converte internamente ai valori loro
+assegnati come numeri in virgola mobile.
+
+Se si desidera approfondire ulteriormente questo argomento, si possono
+trovare programmi di test scritti in C, @command{awk} e Python
+nella directory @file{awklib/eg/test-programs} disponibile
+nella distribuzione di @command{gawk}.
+Tali programmi permettono un confronto tra i linguaggi di
+programmazione, riguardo al modo con cui vengono trattati
+i valori di infinito e quelli NaN.
+
+@ignore
+@c file eg/test-programs/gen-float-table.awk
+function eq(left, right)
+{
+ return left == right
+}
+
+function ne(left, right)
+{
+ return left != right
+}
+
+function lt(left, right)
+{
+ return left < right
+}
+
+function le(left, right)
+{
+ return left <= right
+}
+
+function gt(left, right)
+{
+ return left > right
+}
+
+function ge(left, right)
+{
+ return left >= right
+}
+
+BEGIN {
+ nan = sqrt(-1)
+ inf = -log(0)
+ split("== != < <= > >=", names)
+ names[3] = names[3] " "
+ names[5] = names[5] " "
+ split("eq ne lt le gt ge", funcs)
+
+ compare[1] = 2.0
+ compare[2] = values[1] = -sqrt(-1.0) # nan
+ compare[3] = values[2] = sqrt(-1.0) # -nan
+ compare[4] = values[3] = -log(0.0) # inf
+ compare[5] = values[4] = log(0.0) # -inf
+
+ for (i = 1; i in values; i++) {
+ for (j = 1; j in compare; j++) {
+ for (k = 1; k in names; k++) {
+ the_func = funcs[k]
+ printf("%g %s %g -> %s\n",
+ values[i],
+ names[k],
+ compare[j],
+ @the_func(values[i], compare[j]) ?
+ "true" : "false");
+ }
+ printf("\n");
+ }
+ }
+}
+@c endfile
+@end ignore
+
+@ignore
+@c file eg/test-programs/gen-float-table.c
+#include <stdio.h>
+#include <math.h>
+#include <stdbool.h>
+
+#define def_func(name, op) \
+ bool name(double left, double right) { \
+ return left op right; \
+ }
+
+def_func(eq, ==)
+def_func(ne, !=)
+def_func(lt, <)
+def_func(le, <=)
+def_func(gt, >)
+def_func(ge, >=)
+
+struct {
+ const char *name;
+ bool (*func)(double left, double right);
+} functions[] = {
+ { "==", eq },
+ { "!=", ne },
+ { "< ", lt },
+ { "<=", le },
+ { "> ", gt },
+ { ">=", ge },
+ { 0, 0 }
+};
+
+int main()
+{
+ double values[] = {
+ -sqrt(-1), // nan
+ sqrt(-1), // -nan
+ -log(0.0), // inf
+ log(0.0) // -inf
+ };
+ double compare[] = { 2.0,
+ -sqrt(-1), // nan
+ sqrt(-1), // -nan
+ -log(0.0), // inf
+ log(0.0) // -inf
+ };
+
+ int i, j, k;
+
+ for (i = 0; i < 4; i++) {
+ for (j = 0; j < 5; j++) {
+ for (k = 0; functions[k].name != NULL; k++) {
+ printf("%g %s %g -> %s\n", values[i],
+ functions[k].name,
+ compare[j],
+ functions[k].func(values[i], compare[j]) ? "true" : "false");
+ }
+ printf("\n");
+ }
+ }
+
+ return 0;
+}
+@c endfile
+@end ignore
+
+@ignore
+@c file eg/test-programs/gen-float-table.py
+from math import *
+
+nan = float('NaN')
+inf = float('Inf')
+
+def eq(left, right):
+ return left == right
+
+def ne(left, right):
+ return left != right
+
+def lt(left, right):
+ return left < right
+
+def le(left, right):
+ return left <= right
+
+def gt(left, right):
+ return left > right
+
+def ge(left, right):
+ return left >= right
+
+func_map = {
+ "==": eq,
+ "!=": ne,
+ "< ": lt,
+ "<=": le,
+ "> ": gt,
+ ">=": ge,
+}
+
+compare = [2.0, nan, -nan, inf, -inf]
+values = [nan, -nan, inf, -inf]
+
+for i in range(len(values)):
+ for j in range(len(compare)):
+ for op in func_map:
+ print("%g %s %g -> %s" %
+ (values[i], op, compare[j], func_map[op](values[i], compare[j])))
+
+ print("")
+@c endfile
+@end ignore
+
@node Ottenere la precisione
@subsection Ottenere la precisione voluta
diff --git a/doc/wordlist b/doc/wordlist
index c93eda53..9ce31188 100644
--- a/doc/wordlist
+++ b/doc/wordlist
@@ -316,6 +316,7 @@ NR
NT
NUMCUR
NaN
+NaNs
Nachum
Neacsu
Neacsu's
@@ -483,6 +484,7 @@ VT
Versioning
Vinschen
WIPO
+WONTFIX
Walamazoo
Wallin
Watchpoint
diff --git a/eval.c b/eval.c
index 9e644523..640f939f 100644
--- a/eval.c
+++ b/eval.c
@@ -25,10 +25,8 @@
*/
#include "awk.h"
+#include <math.h>
-extern double pow(double x, double y);
-extern double modf(double x, double *yp);
-extern double fmod(double x, double y);
NODE **fcall_list = NULL;
long fcall_count = 0;
int currule = 0;
@@ -1521,18 +1519,17 @@ eval_condition(NODE *t)
return boolval(t);
}
-typedef enum {
- SCALAR_EQ_NEQ,
- SCALAR_RELATIONAL
-} scalar_cmp_t;
+static bool cmp_doubles(const NODE *t1, const NODE *t2, scalar_cmp_t comparison_type);
+extern bool mpg_cmp_as_numbers(const NODE *t1, const NODE *t2, scalar_cmp_t comparison_type);
/* cmp_scalars -- compare two nodes on the stack */
-static inline int
+static bool
cmp_scalars(scalar_cmp_t comparison_type)
{
NODE *t1, *t2;
int di;
+ bool ret;
t2 = POP_SCALAR();
t1 = TOP();
@@ -1540,12 +1537,91 @@ cmp_scalars(scalar_cmp_t comparison_type)
DEREF(t2);
fatal(_("attempt to use array `%s' in a scalar context"), array_vname(t1));
}
- di = cmp_nodes(t1, t2, comparison_type == SCALAR_EQ_NEQ);
+
+ if ((t1->flags & STRING) != 0 || (t2->flags & STRING) != 0) {
+ bool use_strcmp = (comparison_type == SCALAR_EQ || comparison_type == SCALAR_NEQ);
+ di = cmp_nodes(t1, t2, use_strcmp);
+
+ switch (comparison_type) {
+ case SCALAR_EQ:
+ ret = (di == 0);
+ break;
+ case SCALAR_NEQ:
+ ret = (di != 0);
+ break;
+ case SCALAR_LT:
+ ret = (di < 0);
+ break;
+ case SCALAR_LE:
+ ret = (di <= 0);
+ break;
+ case SCALAR_GT:
+ ret = (di > 0);
+ break;
+ case SCALAR_GE:
+ ret = (di >= 0);
+ break;
+ }
+ } else {
+ fixtype(t1);
+ fixtype(t2);
+
+#ifdef HAVE_MPFR
+ if (do_mpfr)
+ ret = mpg_cmp_as_numbers(t1, t2, comparison_type);
+ else
+#endif
+ ret = cmp_doubles(t1, t2, comparison_type);
+ }
+
DEREF(t1);
DEREF(t2);
- return di;
+ return ret;
}
+
+/* cmp_doubles --- compare two doubles */
+
+static bool
+cmp_doubles(const NODE *t1, const NODE *t2, scalar_cmp_t comparison_type)
+{
+ /*
+ * This routine provides numeric comparisons that should work
+ * the same as in C. It should NOT be used for sorting.
+ */
+
+ bool t1_nan = isnan(t1->numbr);
+ bool t2_nan = isnan(t2->numbr);
+ int ret;
+
+ if ((t1_nan || t2_nan) && comparison_type != SCALAR_NEQ)
+ return false;
+
+ switch (comparison_type) {
+ case SCALAR_EQ:
+ ret = (t1->numbr == t2->numbr);
+ break;
+ case SCALAR_NEQ:
+ ret = (t1->numbr != t2->numbr);
+ break;
+ case SCALAR_LT:
+ ret = (t1->numbr < t2->numbr);
+ break;
+ case SCALAR_LE:
+ ret = (t1->numbr <= t2->numbr);
+ break;
+ case SCALAR_GT:
+ ret = (t1->numbr > t2->numbr);
+ break;
+ case SCALAR_GE:
+ ret = (t1->numbr >= t2->numbr);
+ break;
+ }
+
+ return ret;
+}
+
+
/* op_assign --- assignment operators excluding = */
static void
diff --git a/interpret.h b/interpret.h
index 739f81eb..93a50f24 100644
--- a/interpret.h
+++ b/interpret.h
@@ -486,37 +486,37 @@ uninitialized_scalar:
break;
case Op_equal:
- r = node_Boolean[cmp_scalars(SCALAR_EQ_NEQ) == 0];
+ r = node_Boolean[cmp_scalars(SCALAR_EQ)];
UPREF(r);
REPLACE(r);
break;
case Op_notequal:
- r = node_Boolean[cmp_scalars(SCALAR_EQ_NEQ) != 0];
+ r = node_Boolean[cmp_scalars(SCALAR_NEQ)];
UPREF(r);
REPLACE(r);
break;
case Op_less:
- r = node_Boolean[cmp_scalars(SCALAR_RELATIONAL) < 0];
+ r = node_Boolean[cmp_scalars(SCALAR_LT)];
UPREF(r);
REPLACE(r);
break;
case Op_greater:
- r = node_Boolean[cmp_scalars(SCALAR_RELATIONAL) > 0];
+ r = node_Boolean[cmp_scalars(SCALAR_GT)];
UPREF(r);
REPLACE(r);
break;
case Op_leq:
- r = node_Boolean[cmp_scalars(SCALAR_RELATIONAL) <= 0];
+ r = node_Boolean[cmp_scalars(SCALAR_LE)];
UPREF(r);
REPLACE(r);
break;
case Op_geq:
- r = node_Boolean[cmp_scalars(SCALAR_RELATIONAL) >= 0];
+ r = node_Boolean[cmp_scalars(SCALAR_GE)];
UPREF(r);
REPLACE(r);
break;
diff --git a/mpfr.c b/mpfr.c
index cabc3910..6b8f9c93 100644
--- a/mpfr.c
+++ b/mpfr.c
@@ -476,6 +476,50 @@ mpg_cmp(const NODE *t1, const NODE *t2)
return cmp_awknums(t1, t2);
}
+/* mpg_cmp_as_numbers --- compare two numbers, similar to doubles */
+
+bool
+mpg_cmp_as_numbers(const NODE *t1, const NODE *t2, scalar_cmp_t comparison_type)
+{
+ /*
+ * This routine provides numeric comparisons that should work
+ * the same as in C. It should NOT be used for sorting.
+ */
+
+ bool t1_nan = mpfr_nan_p(t1->mpg_numbr);
+ bool t2_nan = mpfr_nan_p(t2->mpg_numbr);
+ int ret;
+
+ // MPFR is different than native doubles...
+ if (t1_nan || t2_nan)
+ return comparison_type == SCALAR_NEQ;
+
+ int di = mpg_cmp(t1, t2);
+
+ switch (comparison_type) {
+ case SCALAR_EQ:
+ ret = (di == 0);
+ break;
+ case SCALAR_NEQ:
+ ret = (di != 0);
+ break;
+ case SCALAR_LT:
+ ret = (di < 0);
+ break;
+ case SCALAR_LE:
+ ret = (di <= 0);
+ break;
+ case SCALAR_GT:
+ ret = (di > 0);
+ break;
+ case SCALAR_GE:
+ ret = (di >= 0);
+ break;
+ }
+
+ return ret;
+}
+
/*
* mpg_update_var --- update NR or FNR.
diff --git a/node.c b/node.c
index 12d7a046..c22c06ab 100644
--- a/node.c
+++ b/node.c
@@ -370,7 +370,7 @@ int
cmp_awknums(const NODE *t1, const NODE *t2)
{
/*
- * This routine is also used to sort numeric array indices or values.
+ * This routine is used to sort numeric array indices or values.
* For the purposes of sorting, NaN is considered greater than
* any other value, and all NaN values are considered equivalent and equal.
* This isn't in compliance with IEEE standard, but compliance w.r.t. NaN
@@ -390,7 +390,6 @@ cmp_awknums(const NODE *t1, const NODE *t2)
return 1;
}
-
/* make_str_node --- make a string node */
NODE *