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 60fe7772..2c8caa01 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -90,6 +90,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 71facfa7..7fc623eb 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 fc5dc31e..867a07f9 100644
--- a/builtin.c
+++ b/builtin.c
@@ -4275,7 +4275,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 7326172d..b06cc6ad 100644
--- a/doc/ChangeLog
+++ b/doc/ChangeLog
@@ -42,12 +42,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 84aaf435..ee2526ec 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.
@@ -6919,8 +6920,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
@@ -12812,7 +12813,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()'
@@ -24195,18 +24196,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.
@@ -24265,11 +24258,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
@@ -24362,6 +24350,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
@@ -24426,7 +24415,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
..........................
@@ -24474,6 +24463,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
@@ -37986,603 +38033,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-1213697
-Node: Fields213734
-Node: Nonconstant Fields216475
-Ref: Nonconstant Fields-Footnote-1218711
-Node: Changing Fields218915
-Node: Field Separators224946
-Node: Default Field Splitting227644
-Node: Regexp Field Splitting228762
-Node: Single Character Fields232115
-Node: Command Line Field Separator233175
-Node: Full Line Fields236393
-Ref: Full Line Fields-Footnote-1237915
-Ref: Full Line Fields-Footnote-2237961
-Node: Field Splitting Summary238062
-Node: Constant Size240136
-Node: Fixed width data240868
-Node: Skipping intervening244335
-Node: Allowing trailing data245133
-Node: Fields with fixed data246170
-Node: Splitting By Content247688
-Ref: Splitting By Content-Footnote-1251471
-Node: More CSV251634
-Node: Testing field creation253226
-Node: Multiple Line254851
-Node: Getline261128
-Node: Plain Getline263597
-Node: Getline/Variable266170
-Node: Getline/File267321
-Node: Getline/Variable/File268709
-Ref: Getline/Variable/File-Footnote-1270314
-Node: Getline/Pipe270402
-Node: Getline/Variable/Pipe273106
-Node: Getline/Coprocess274241
-Node: Getline/Variable/Coprocess275508
-Node: Getline Notes276250
-Node: Getline Summary279047
-Ref: table-getline-variants279471
-Node: Read Timeout280219
-Ref: Read Timeout-Footnote-1284125
-Node: Retrying Input284183
-Node: Command-line directories285382
-Node: Input Summary286288
-Node: Input Exercises289460
-Node: Printing289894
-Node: Print291728
-Node: Print Examples293185
-Node: Output Separators295965
-Node: OFMT297982
-Node: Printf299338
-Node: Basic Printf300123
-Node: Control Letters301697
-Node: Format Modifiers306861
-Node: Printf Examples312876
-Node: Redirection315362
-Node: Special FD322203
-Ref: Special FD-Footnote-1325371
-Node: Special Files325445
-Node: Other Inherited Files326062
-Node: Special Network327063
-Node: Special Caveats327923
-Node: Close Files And Pipes328872
-Ref: table-close-pipe-return-values335779
-Ref: Close Files And Pipes-Footnote-1336592
-Ref: Close Files And Pipes-Footnote-2336740
-Node: Nonfatal336892
-Node: Output Summary339230
-Node: Output Exercises340452
-Node: Expressions341131
-Node: Values342319
-Node: Constants342997
-Node: Scalar Constants343688
-Ref: Scalar Constants-Footnote-1346198
-Node: Nondecimal-numbers346448
-Node: Regexp Constants349449
-Node: Using Constant Regexps349975
-Node: Standard Regexp Constants350597
-Node: Strong Regexp Constants353785
-Node: Variables356797
-Node: Using Variables357454
-Node: Assignment Options359364
-Node: Conversion361835
-Node: Strings And Numbers362359
-Ref: Strings And Numbers-Footnote-1365422
-Node: Locale influences conversions365531
-Ref: table-locale-affects368289
-Node: All Operators368907
-Node: Arithmetic Ops369536
-Node: Concatenation372252
-Ref: Concatenation-Footnote-1375099
-Node: Assignment Ops375206
-Ref: table-assign-ops380197
-Node: Increment Ops381510
-Node: Truth Values and Conditions384970
-Node: Truth Values386044
-Node: Typing and Comparison387092
-Node: Variable Typing387912
-Ref: Variable Typing-Footnote-1394375
-Ref: Variable Typing-Footnote-2394447
-Node: Comparison Operators394524
-Ref: table-relational-ops394943
-Node: POSIX String Comparison398438
-Ref: POSIX String Comparison-Footnote-1400133
-Ref: POSIX String Comparison-Footnote-2400272
-Node: Boolean Ops400356
-Ref: Boolean Ops-Footnote-1404838
-Node: Conditional Exp404930
-Node: Function Calls406666
-Node: Precedence410543
-Node: Locales414202
-Node: Expressions Summary415834
-Node: Patterns and Actions418407
-Node: Pattern Overview419527
-Node: Regexp Patterns421204
-Node: Expression Patterns421746
-Node: Ranges425527
-Node: BEGIN/END428635
-Node: Using BEGIN/END429396
-Ref: Using BEGIN/END-Footnote-1432150
-Node: I/O And BEGIN/END432256
-Node: BEGINFILE/ENDFILE434569
-Node: Empty437800
-Node: Using Shell Variables438117
-Node: Action Overview440391
-Node: Statements442716
-Node: If Statement444564
-Node: While Statement446059
-Node: Do Statement448087
-Node: For Statement449235
-Node: Switch Statement452406
-Node: Break Statement454847
-Node: Continue Statement456939
-Node: Next Statement458766
-Node: Nextfile Statement461149
-Node: Exit Statement463838
-Node: Built-in Variables466241
-Node: User-modified467374
-Node: Auto-set475141
-Ref: Auto-set-Footnote-1491948
-Ref: Auto-set-Footnote-2492154
-Node: ARGC and ARGV492210
-Node: Pattern Action Summary496423
-Node: Arrays498853
-Node: Array Basics500182
-Node: Array Intro501026
-Ref: figure-array-elements503001
-Ref: Array Intro-Footnote-1505705
-Node: Reference to Elements505833
-Node: Assigning Elements508297
-Node: Array Example508788
-Node: Scanning an Array510547
-Node: Controlling Scanning513569
-Ref: Controlling Scanning-Footnote-1520025
-Node: Numeric Array Subscripts520341
-Node: Uninitialized Subscripts522525
-Node: Delete524144
-Ref: Delete-Footnote-1526896
-Node: Multidimensional526953
-Node: Multiscanning530048
-Node: Arrays of Arrays531639
-Node: Arrays Summary536407
-Node: Functions538500
-Node: Built-in539538
-Node: Calling Built-in540619
-Node: Numeric Functions542615
-Ref: Numeric Functions-Footnote-1546643
-Ref: Numeric Functions-Footnote-2547291
-Ref: Numeric Functions-Footnote-3547339
-Node: String Functions547611
-Ref: String Functions-Footnote-1571752
-Ref: String Functions-Footnote-2571880
-Ref: String Functions-Footnote-3572128
-Node: Gory Details572215
-Ref: table-sub-escapes574006
-Ref: table-sub-proposed575525
-Ref: table-posix-sub576888
-Ref: table-gensub-escapes578429
-Ref: Gory Details-Footnote-1579252
-Node: I/O Functions579406
-Ref: table-system-return-values585860
-Ref: I/O Functions-Footnote-1587940
-Ref: I/O Functions-Footnote-2588088
-Node: Time Functions588208
-Ref: Time Functions-Footnote-1598879
-Ref: Time Functions-Footnote-2598947
-Ref: Time Functions-Footnote-3599105
-Ref: Time Functions-Footnote-4599216
-Ref: Time Functions-Footnote-5599328
-Ref: Time Functions-Footnote-6599555
-Node: Bitwise Functions599821
-Ref: table-bitwise-ops600415
-Ref: Bitwise Functions-Footnote-1606478
-Ref: Bitwise Functions-Footnote-2606651
-Node: Type Functions606842
-Node: I18N Functions609705
-Node: User-defined611356
-Node: Definition Syntax612168
-Ref: Definition Syntax-Footnote-1617862
-Node: Function Example617933
-Ref: Function Example-Footnote-1620855
-Node: Function Calling620877
-Node: Calling A Function621465
-Node: Variable Scope622423
-Node: Pass By Value/Reference625417
-Node: Function Caveats628061
-Ref: Function Caveats-Footnote-1630108
-Node: Return Statement630228
-Node: Dynamic Typing633207
-Node: Indirect Calls634137
-Ref: Indirect Calls-Footnote-1644389
-Node: Functions Summary644517
-Node: Library Functions647222
-Ref: Library Functions-Footnote-1650829
-Ref: Library Functions-Footnote-2650972
-Node: Library Names651143
-Ref: Library Names-Footnote-1654810
-Ref: Library Names-Footnote-2655033
-Node: General Functions655119
-Node: Strtonum Function656222
-Node: Assert Function659244
-Node: Round Function662570
-Node: Cliff Random Function664110
-Node: Ordinal Functions665126
-Ref: Ordinal Functions-Footnote-1668189
-Ref: Ordinal Functions-Footnote-2668441
-Node: Join Function668651
-Ref: Join Function-Footnote-1670421
-Node: Getlocaltime Function670621
-Node: Readfile Function674363
-Node: Shell Quoting676340
-Node: Data File Management677741
-Node: Filetrans Function678373
-Node: Rewind Function682469
-Node: File Checking684378
-Ref: File Checking-Footnote-1685712
-Node: Empty Files685913
-Node: Ignoring Assigns687892
-Node: Getopt Function689442
-Ref: Getopt Function-Footnote-1704653
-Node: Passwd Functions704853
-Ref: Passwd Functions-Footnote-1713692
-Node: Group Functions713780
-Ref: Group Functions-Footnote-1721678
-Node: Walking Arrays721885
-Node: Library Functions Summary724893
-Node: Library Exercises726299
-Node: Sample Programs726764
-Node: Running Examples727534
-Node: Clones728262
-Node: Cut Program729486
-Node: Egrep Program739626
-Node: Id Program748637
-Node: Split Program758584
-Ref: Split Program-Footnote-1768474
-Node: Tee Program768647
-Node: Uniq Program771437
-Node: Wc Program779025
-Node: Bytes vs. Characters779422
-Node: Using extensions780970
-Node: wc program781724
-Node: Miscellaneous Programs786589
-Node: Dupword Program787802
-Node: Alarm Program789832
-Node: Translate Program794687
-Ref: Translate Program-Footnote-1799252
-Node: Labels Program799522
-Ref: Labels Program-Footnote-1802873
-Node: Word Sorting802957
-Node: History Sorting807029
-Node: Extract Program809254
-Node: Simple Sed817308
-Node: Igawk Program820382
-Ref: Igawk Program-Footnote-1834713
-Ref: Igawk Program-Footnote-2834915
-Ref: Igawk Program-Footnote-3835037
-Node: Anagram Program835152
-Node: Signature Program838214
-Node: Programs Summary839461
-Node: Programs Exercises840675
-Ref: Programs Exercises-Footnote-1844805
-Node: Advanced Features844891
-Node: Nondecimal Data846958
-Node: Array Sorting848549
-Node: Controlling Array Traversal849249
-Ref: Controlling Array Traversal-Footnote-1857617
-Node: Array Sorting Functions857735
-Ref: Array Sorting Functions-Footnote-1862826
-Node: Two-way I/O863022
-Ref: Two-way I/O-Footnote-1870743
-Ref: Two-way I/O-Footnote-2870930
-Node: TCP/IP Networking871012
-Node: Profiling874130
-Node: Extension Philosophy883439
-Node: Advanced Features Summary884890
-Node: Internationalization886889
-Node: I18N and L10N888369
-Node: Explaining gettext889056
-Ref: Explaining gettext-Footnote-1894948
-Ref: Explaining gettext-Footnote-2895133
-Node: Programmer i18n895298
-Ref: Programmer i18n-Footnote-1900247
-Node: Translator i18n900296
-Node: String Extraction901090
-Ref: String Extraction-Footnote-1902222
-Node: Printf Ordering902308
-Ref: Printf Ordering-Footnote-1905094
-Node: I18N Portability905158
-Ref: I18N Portability-Footnote-1907614
-Node: I18N Example907677
-Ref: I18N Example-Footnote-1910952
-Ref: I18N Example-Footnote-2911025
-Node: Gawk I18N911134
-Node: I18N Summary911783
-Node: Debugger913124
-Node: Debugging914124
-Node: Debugging Concepts914565
-Node: Debugging Terms916374
-Node: Awk Debugging918949
-Ref: Awk Debugging-Footnote-1919894
-Node: Sample Debugging Session920026
-Node: Debugger Invocation920560
-Node: Finding The Bug921946
-Node: List of Debugger Commands928420
-Node: Breakpoint Control929753
-Node: Debugger Execution Control933447
-Node: Viewing And Changing Data936809
-Node: Execution Stack940350
-Node: Debugger Info941987
-Node: Miscellaneous Debugger Commands946058
-Node: Readline Support951120
-Node: Limitations952016
-Node: Debugging Summary954570
-Node: Namespaces955849
-Node: Global Namespace956960
-Node: Qualified Names958358
-Node: Default Namespace959357
-Node: Changing The Namespace960098
-Node: Naming Rules961712
-Node: Internal Name Management963560
-Node: Namespace Example964602
-Node: Namespace And Features967164
-Node: Namespace Summary968599
-Node: Arbitrary Precision Arithmetic970076
-Node: Computer Arithmetic971563
-Ref: table-numeric-ranges975329
-Ref: table-floating-point-ranges975822
-Ref: Computer Arithmetic-Footnote-1976480
-Node: Math Definitions976537
-Ref: table-ieee-formats979853
-Ref: Math Definitions-Footnote-1980456
-Node: MPFR features980561
-Node: FP Math Caution982279
-Ref: FP Math Caution-Footnote-1983351
-Node: Inexactness of computations983720
-Node: Inexact representation984680
-Node: Comparing FP Values986040
-Node: Errors accumulate987281
-Node: Getting Accuracy988714
-Node: Try To Round991424
-Node: Setting precision992323
-Ref: table-predefined-precision-strings993020
-Node: Setting the rounding mode994850
-Ref: table-gawk-rounding-modes995224
-Ref: Setting the rounding mode-Footnote-1999155
-Node: Arbitrary Precision Integers999334
-Ref: Arbitrary Precision Integers-Footnote-11002509
-Node: Checking for MPFR1002658
-Node: POSIX Floating Point Problems1004132
-Ref: POSIX Floating Point Problems-Footnote-11008417
-Node: Floating point summary1008455
-Node: Dynamic Extensions1010645
-Node: Extension Intro1012198
-Node: Plugin License1013464
-Node: Extension Mechanism Outline1014261
-Ref: figure-load-extension1014700
-Ref: figure-register-new-function1016265
-Ref: figure-call-new-function1017357
-Node: Extension API Description1019419
-Node: Extension API Functions Introduction1021132
-Ref: table-api-std-headers1022968
-Node: General Data Types1027217
-Ref: General Data Types-Footnote-11035847
-Node: Memory Allocation Functions1036146
-Ref: Memory Allocation Functions-Footnote-11040647
-Node: Constructor Functions1040746
-Node: API Ownership of MPFR and GMP Values1044212
-Node: Registration Functions1045525
-Node: Extension Functions1046225
-Node: Exit Callback Functions1051547
-Node: Extension Version String1052797
-Node: Input Parsers1053460
-Node: Output Wrappers1066181
-Node: Two-way processors1070693
-Node: Printing Messages1072958
-Ref: Printing Messages-Footnote-11074129
-Node: Updating ERRNO1074282
-Node: Requesting Values1075021
-Ref: table-value-types-returned1075758
-Node: Accessing Parameters1076694
-Node: Symbol Table Access1077931
-Node: Symbol table by name1078443
-Ref: Symbol table by name-Footnote-11081467
-Node: Symbol table by cookie1081595
-Ref: Symbol table by cookie-Footnote-11085780
-Node: Cached values1085844
-Ref: Cached values-Footnote-11089380
-Node: Array Manipulation1089533
-Ref: Array Manipulation-Footnote-11090624
-Node: Array Data Types1090661
-Ref: Array Data Types-Footnote-11093319
-Node: Array Functions1093411
-Node: Flattening Arrays1097909
-Node: Creating Arrays1104885
-Node: Redirection API1109652
-Node: Extension API Variables1112485
-Node: Extension Versioning1113196
-Ref: gawk-api-version1113625
-Node: Extension GMP/MPFR Versioning1115356
-Node: Extension API Informational Variables1116984
-Node: Extension API Boilerplate1118057
-Node: Changes from API V11122031
-Node: Finding Extensions1123603
-Node: Extension Example1124162
-Node: Internal File Description1124960
-Node: Internal File Ops1129040
-Ref: Internal File Ops-Footnote-11140390
-Node: Using Internal File Ops1140530
-Ref: Using Internal File Ops-Footnote-11142913
-Node: Extension Samples1143187
-Node: Extension Sample File Functions1144716
-Node: Extension Sample Fnmatch1152365
-Node: Extension Sample Fork1153852
-Node: Extension Sample Inplace1155070
-Node: Extension Sample Ord1158696
-Node: Extension Sample Readdir1159532
-Ref: table-readdir-file-types1160421
-Node: Extension Sample Revout1161488
-Node: Extension Sample Rev2way1162077
-Node: Extension Sample Read write array1162817
-Node: Extension Sample Readfile1164759
-Node: Extension Sample Time1165854
-Node: Extension Sample API Tests1167606
-Node: gawkextlib1168098
-Node: Extension summary1171016
-Node: Extension Exercises1174718
-Node: Language History1175960
-Node: V7/SVR3.11177616
-Node: SVR41179768
-Node: POSIX1181202
-Node: BTL1182583
-Node: POSIX/GNU1183312
-Node: Feature History1189090
-Node: Common Extensions1205409
-Node: Ranges and Locales1206692
-Ref: Ranges and Locales-Footnote-11211308
-Ref: Ranges and Locales-Footnote-21211335
-Ref: Ranges and Locales-Footnote-31211570
-Node: Contributors1211793
-Node: History summary1217790
-Node: Installation1219170
-Node: Gawk Distribution1220114
-Node: Getting1220598
-Node: Extracting1221561
-Node: Distribution contents1223199
-Node: Unix Installation1229679
-Node: Quick Installation1230361
-Node: Shell Startup Files1232775
-Node: Additional Configuration Options1233864
-Node: Configuration Philosophy1236179
-Node: Non-Unix Installation1238548
-Node: PC Installation1239008
-Node: PC Binary Installation1239846
-Node: PC Compiling1240281
-Node: PC Using1241398
-Node: Cygwin1244951
-Node: MSYS1246175
-Node: VMS Installation1246777
-Node: VMS Compilation1247568
-Ref: VMS Compilation-Footnote-11248797
-Node: VMS Dynamic Extensions1248855
-Node: VMS Installation Details1250540
-Node: VMS Running1252793
-Node: VMS GNV1257072
-Node: VMS Old Gawk1257807
-Node: Bugs1258278
-Node: Bug address1258941
-Node: Usenet1261923
-Node: Maintainers1262927
-Node: Other Versions1264112
-Node: Installation summary1271200
-Node: Notes1272409
-Node: Compatibility Mode1273203
-Node: Additions1273985
-Node: Accessing The Source1274910
-Node: Adding Code1276347
-Node: New Ports1282566
-Node: Derived Files1286941
-Ref: Derived Files-Footnote-11292601
-Ref: Derived Files-Footnote-21292636
-Ref: Derived Files-Footnote-31293234
-Node: Future Extensions1293348
-Node: Implementation Limitations1294006
-Node: Extension Design1295216
-Node: Old Extension Problems1296360
-Ref: Old Extension Problems-Footnote-11297878
-Node: Extension New Mechanism Goals1297935
-Ref: Extension New Mechanism Goals-Footnote-11301299
-Node: Extension Other Design Decisions1301488
-Node: Extension Future Growth1303601
-Node: Notes summary1304207
-Node: Basic Concepts1305365
-Node: Basic High Level1306046
-Ref: figure-general-flow1306328
-Ref: figure-process-flow1307013
-Ref: Basic High Level-Footnote-11310314
-Node: Basic Data Typing1310499
-Node: Glossary1313827
-Node: Copying1345712
-Node: GNU Free Documentation License1383255
-Node: Index1408375
+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-1213776
+Node: Fields213813
+Node: Nonconstant Fields216554
+Ref: Nonconstant Fields-Footnote-1218790
+Node: Changing Fields218994
+Node: Field Separators225025
+Node: Default Field Splitting227723
+Node: Regexp Field Splitting228841
+Node: Single Character Fields232194
+Node: Command Line Field Separator233254
+Node: Full Line Fields236472
+Ref: Full Line Fields-Footnote-1237994
+Ref: Full Line Fields-Footnote-2238040
+Node: Field Splitting Summary238141
+Node: Constant Size240215
+Node: Fixed width data240947
+Node: Skipping intervening244414
+Node: Allowing trailing data245212
+Node: Fields with fixed data246249
+Node: Splitting By Content247767
+Ref: Splitting By Content-Footnote-1251550
+Node: More CSV251713
+Node: Testing field creation253305
+Node: Multiple Line254930
+Node: Getline261207
+Node: Plain Getline263676
+Node: Getline/Variable266249
+Node: Getline/File267400
+Node: Getline/Variable/File268788
+Ref: Getline/Variable/File-Footnote-1270393
+Node: Getline/Pipe270481
+Node: Getline/Variable/Pipe273185
+Node: Getline/Coprocess274320
+Node: Getline/Variable/Coprocess275587
+Node: Getline Notes276329
+Node: Getline Summary279126
+Ref: table-getline-variants279550
+Node: Read Timeout280298
+Ref: Read Timeout-Footnote-1284204
+Node: Retrying Input284262
+Node: Command-line directories285461
+Node: Input Summary286367
+Node: Input Exercises289539
+Node: Printing289973
+Node: Print291807
+Node: Print Examples293264
+Node: Output Separators296044
+Node: OFMT298061
+Node: Printf299417
+Node: Basic Printf300202
+Node: Control Letters301776
+Node: Format Modifiers306938
+Node: Printf Examples312953
+Node: Redirection315439
+Node: Special FD322280
+Ref: Special FD-Footnote-1325448
+Node: Special Files325522
+Node: Other Inherited Files326139
+Node: Special Network327140
+Node: Special Caveats328000
+Node: Close Files And Pipes328949
+Ref: table-close-pipe-return-values335856
+Ref: Close Files And Pipes-Footnote-1336669
+Ref: Close Files And Pipes-Footnote-2336817
+Node: Nonfatal336969
+Node: Output Summary339307
+Node: Output Exercises340529
+Node: Expressions341208
+Node: Values342396
+Node: Constants343074
+Node: Scalar Constants343765
+Ref: Scalar Constants-Footnote-1346275
+Node: Nondecimal-numbers346525
+Node: Regexp Constants349526
+Node: Using Constant Regexps350052
+Node: Standard Regexp Constants350674
+Node: Strong Regexp Constants353862
+Node: Variables356874
+Node: Using Variables357531
+Node: Assignment Options359441
+Node: Conversion361912
+Node: Strings And Numbers362436
+Ref: Strings And Numbers-Footnote-1365499
+Node: Locale influences conversions365608
+Ref: table-locale-affects368366
+Node: All Operators368984
+Node: Arithmetic Ops369613
+Node: Concatenation372329
+Ref: Concatenation-Footnote-1375176
+Node: Assignment Ops375283
+Ref: table-assign-ops380274
+Node: Increment Ops381587
+Node: Truth Values and Conditions385047
+Node: Truth Values386121
+Node: Typing and Comparison387169
+Node: Variable Typing387989
+Ref: Variable Typing-Footnote-1394452
+Ref: Variable Typing-Footnote-2394524
+Node: Comparison Operators394601
+Ref: table-relational-ops395020
+Node: POSIX String Comparison398515
+Ref: POSIX String Comparison-Footnote-1400210
+Ref: POSIX String Comparison-Footnote-2400349
+Node: Boolean Ops400433
+Ref: Boolean Ops-Footnote-1404915
+Node: Conditional Exp405007
+Node: Function Calls406743
+Node: Precedence410620
+Node: Locales414279
+Node: Expressions Summary415911
+Node: Patterns and Actions418484
+Node: Pattern Overview419604
+Node: Regexp Patterns421281
+Node: Expression Patterns421823
+Node: Ranges425604
+Node: BEGIN/END428712
+Node: Using BEGIN/END429473
+Ref: Using BEGIN/END-Footnote-1432227
+Node: I/O And BEGIN/END432333
+Node: BEGINFILE/ENDFILE434646
+Node: Empty437877
+Node: Using Shell Variables438194
+Node: Action Overview440468
+Node: Statements442793
+Node: If Statement444641
+Node: While Statement446136
+Node: Do Statement448164
+Node: For Statement449312
+Node: Switch Statement452483
+Node: Break Statement454924
+Node: Continue Statement457016
+Node: Next Statement458843
+Node: Nextfile Statement461226
+Node: Exit Statement463915
+Node: Built-in Variables466318
+Node: User-modified467451
+Node: Auto-set475218
+Ref: Auto-set-Footnote-1492025
+Ref: Auto-set-Footnote-2492231
+Node: ARGC and ARGV492287
+Node: Pattern Action Summary496500
+Node: Arrays498930
+Node: Array Basics500259
+Node: Array Intro501103
+Ref: figure-array-elements503078
+Ref: Array Intro-Footnote-1505782
+Node: Reference to Elements505910
+Node: Assigning Elements508374
+Node: Array Example508865
+Node: Scanning an Array510624
+Node: Controlling Scanning513646
+Ref: Controlling Scanning-Footnote-1520102
+Node: Numeric Array Subscripts520418
+Node: Uninitialized Subscripts522602
+Node: Delete524221
+Ref: Delete-Footnote-1526973
+Node: Multidimensional527030
+Node: Multiscanning530125
+Node: Arrays of Arrays531716
+Node: Arrays Summary536484
+Node: Functions538577
+Node: Built-in539615
+Node: Calling Built-in540696
+Node: Numeric Functions542692
+Ref: Numeric Functions-Footnote-1546718
+Ref: Numeric Functions-Footnote-2547366
+Ref: Numeric Functions-Footnote-3547414
+Node: String Functions547686
+Ref: String Functions-Footnote-1571827
+Ref: String Functions-Footnote-2571955
+Ref: String Functions-Footnote-3572203
+Node: Gory Details572290
+Ref: table-sub-escapes574081
+Ref: table-sub-proposed575600
+Ref: table-posix-sub576963
+Ref: table-gensub-escapes578504
+Ref: Gory Details-Footnote-1579327
+Node: I/O Functions579481
+Ref: table-system-return-values585935
+Ref: I/O Functions-Footnote-1588015
+Ref: I/O Functions-Footnote-2588163
+Node: Time Functions588283
+Ref: Time Functions-Footnote-1598954
+Ref: Time Functions-Footnote-2599022
+Ref: Time Functions-Footnote-3599180
+Ref: Time Functions-Footnote-4599291
+Ref: Time Functions-Footnote-5599403
+Ref: Time Functions-Footnote-6599630
+Node: Bitwise Functions599896
+Ref: table-bitwise-ops600490
+Ref: Bitwise Functions-Footnote-1606553
+Ref: Bitwise Functions-Footnote-2606726
+Node: Type Functions606917
+Node: I18N Functions609780
+Node: User-defined611431
+Node: Definition Syntax612243
+Ref: Definition Syntax-Footnote-1617937
+Node: Function Example618008
+Ref: Function Example-Footnote-1620930
+Node: Function Calling620952
+Node: Calling A Function621540
+Node: Variable Scope622498
+Node: Pass By Value/Reference625492
+Node: Function Caveats628136
+Ref: Function Caveats-Footnote-1630183
+Node: Return Statement630303
+Node: Dynamic Typing633282
+Node: Indirect Calls634212
+Ref: Indirect Calls-Footnote-1644464
+Node: Functions Summary644592
+Node: Library Functions647297
+Ref: Library Functions-Footnote-1650904
+Ref: Library Functions-Footnote-2651047
+Node: Library Names651218
+Ref: Library Names-Footnote-1654885
+Ref: Library Names-Footnote-2655108
+Node: General Functions655194
+Node: Strtonum Function656297
+Node: Assert Function659319
+Node: Round Function662645
+Node: Cliff Random Function664185
+Node: Ordinal Functions665201
+Ref: Ordinal Functions-Footnote-1668264
+Ref: Ordinal Functions-Footnote-2668516
+Node: Join Function668726
+Ref: Join Function-Footnote-1670496
+Node: Getlocaltime Function670696
+Node: Readfile Function674438
+Node: Shell Quoting676415
+Node: Data File Management677816
+Node: Filetrans Function678448
+Node: Rewind Function682544
+Node: File Checking684453
+Ref: File Checking-Footnote-1685787
+Node: Empty Files685988
+Node: Ignoring Assigns687967
+Node: Getopt Function689517
+Ref: Getopt Function-Footnote-1704728
+Node: Passwd Functions704928
+Ref: Passwd Functions-Footnote-1713767
+Node: Group Functions713855
+Ref: Group Functions-Footnote-1721753
+Node: Walking Arrays721960
+Node: Library Functions Summary724968
+Node: Library Exercises726374
+Node: Sample Programs726839
+Node: Running Examples727609
+Node: Clones728337
+Node: Cut Program729561
+Node: Egrep Program739701
+Node: Id Program748712
+Node: Split Program758659
+Ref: Split Program-Footnote-1768549
+Node: Tee Program768722
+Node: Uniq Program771512
+Node: Wc Program779100
+Node: Bytes vs. Characters779497
+Node: Using extensions781045
+Node: wc program781799
+Node: Miscellaneous Programs786664
+Node: Dupword Program787877
+Node: Alarm Program789907
+Node: Translate Program794762
+Ref: Translate Program-Footnote-1799327
+Node: Labels Program799597
+Ref: Labels Program-Footnote-1802948
+Node: Word Sorting803032
+Node: History Sorting807104
+Node: Extract Program809329
+Node: Simple Sed817383
+Node: Igawk Program820457
+Ref: Igawk Program-Footnote-1834788
+Ref: Igawk Program-Footnote-2834990
+Ref: Igawk Program-Footnote-3835112
+Node: Anagram Program835227
+Node: Signature Program838289
+Node: Programs Summary839536
+Node: Programs Exercises840750
+Ref: Programs Exercises-Footnote-1844880
+Node: Advanced Features844966
+Node: Nondecimal Data847033
+Node: Array Sorting848624
+Node: Controlling Array Traversal849324
+Ref: Controlling Array Traversal-Footnote-1857692
+Node: Array Sorting Functions857810
+Ref: Array Sorting Functions-Footnote-1862901
+Node: Two-way I/O863097
+Ref: Two-way I/O-Footnote-1870818
+Ref: Two-way I/O-Footnote-2871005
+Node: TCP/IP Networking871087
+Node: Profiling874205
+Node: Extension Philosophy883514
+Node: Advanced Features Summary884965
+Node: Internationalization886964
+Node: I18N and L10N888444
+Node: Explaining gettext889131
+Ref: Explaining gettext-Footnote-1895023
+Ref: Explaining gettext-Footnote-2895208
+Node: Programmer i18n895373
+Ref: Programmer i18n-Footnote-1900322
+Node: Translator i18n900371
+Node: String Extraction901165
+Ref: String Extraction-Footnote-1902297
+Node: Printf Ordering902383
+Ref: Printf Ordering-Footnote-1905169
+Node: I18N Portability905233
+Ref: I18N Portability-Footnote-1907689
+Node: I18N Example907752
+Ref: I18N Example-Footnote-1911027
+Ref: I18N Example-Footnote-2911100
+Node: Gawk I18N911209
+Node: I18N Summary911858
+Node: Debugger913199
+Node: Debugging914199
+Node: Debugging Concepts914640
+Node: Debugging Terms916449
+Node: Awk Debugging919024
+Ref: Awk Debugging-Footnote-1919969
+Node: Sample Debugging Session920101
+Node: Debugger Invocation920635
+Node: Finding The Bug922021
+Node: List of Debugger Commands928495
+Node: Breakpoint Control929828
+Node: Debugger Execution Control933522
+Node: Viewing And Changing Data936884
+Node: Execution Stack940425
+Node: Debugger Info942062
+Node: Miscellaneous Debugger Commands946133
+Node: Readline Support951195
+Node: Limitations952091
+Node: Debugging Summary954645
+Node: Namespaces955924
+Node: Global Namespace957035
+Node: Qualified Names958433
+Node: Default Namespace959432
+Node: Changing The Namespace960173
+Node: Naming Rules961787
+Node: Internal Name Management963635
+Node: Namespace Example964677
+Node: Namespace And Features967239
+Node: Namespace Summary968674
+Node: Arbitrary Precision Arithmetic970151
+Node: Computer Arithmetic971638
+Ref: table-numeric-ranges975404
+Ref: table-floating-point-ranges975897
+Ref: Computer Arithmetic-Footnote-1976555
+Node: Math Definitions976612
+Ref: table-ieee-formats979588
+Node: MPFR features980155
+Node: FP Math Caution981873
+Ref: FP Math Caution-Footnote-1982945
+Node: Inexactness of computations983314
+Node: Inexact representation984345
+Node: Comparing FP Values985705
+Node: Errors accumulate986946
+Node: Strange values988402
+Ref: Strange values-Footnote-1990990
+Node: Getting Accuracy991095
+Node: Try To Round993805
+Node: Setting precision994704
+Ref: table-predefined-precision-strings995401
+Node: Setting the rounding mode997231
+Ref: table-gawk-rounding-modes997605
+Ref: Setting the rounding mode-Footnote-11001536
+Node: Arbitrary Precision Integers1001715
+Ref: Arbitrary Precision Integers-Footnote-11004890
+Node: Checking for MPFR1005039
+Node: POSIX Floating Point Problems1006513
+Ref: POSIX Floating Point Problems-Footnote-11010798
+Node: Floating point summary1010836
+Node: Dynamic Extensions1013026
+Node: Extension Intro1014579
+Node: Plugin License1015845
+Node: Extension Mechanism Outline1016642
+Ref: figure-load-extension1017081
+Ref: figure-register-new-function1018646
+Ref: figure-call-new-function1019738
+Node: Extension API Description1021800
+Node: Extension API Functions Introduction1023513
+Ref: table-api-std-headers1025349
+Node: General Data Types1029598
+Ref: General Data Types-Footnote-11038228
+Node: Memory Allocation Functions1038527
+Ref: Memory Allocation Functions-Footnote-11043028
+Node: Constructor Functions1043127
+Node: API Ownership of MPFR and GMP Values1046593
+Node: Registration Functions1047906
+Node: Extension Functions1048606
+Node: Exit Callback Functions1053928
+Node: Extension Version String1055178
+Node: Input Parsers1055841
+Node: Output Wrappers1068562
+Node: Two-way processors1073074
+Node: Printing Messages1075339
+Ref: Printing Messages-Footnote-11076510
+Node: Updating ERRNO1076663
+Node: Requesting Values1077402
+Ref: table-value-types-returned1078139
+Node: Accessing Parameters1079075
+Node: Symbol Table Access1080312
+Node: Symbol table by name1080824
+Ref: Symbol table by name-Footnote-11083848
+Node: Symbol table by cookie1083976
+Ref: Symbol table by cookie-Footnote-11088161
+Node: Cached values1088225
+Ref: Cached values-Footnote-11091761
+Node: Array Manipulation1091914
+Ref: Array Manipulation-Footnote-11093005
+Node: Array Data Types1093042
+Ref: Array Data Types-Footnote-11095700
+Node: Array Functions1095792
+Node: Flattening Arrays1100290
+Node: Creating Arrays1107266
+Node: Redirection API1112033
+Node: Extension API Variables1114866
+Node: Extension Versioning1115577
+Ref: gawk-api-version1116006
+Node: Extension GMP/MPFR Versioning1117737
+Node: Extension API Informational Variables1119365
+Node: Extension API Boilerplate1120438
+Node: Changes from API V11124412
+Node: Finding Extensions1125984
+Node: Extension Example1126543
+Node: Internal File Description1127341
+Node: Internal File Ops1131421
+Ref: Internal File Ops-Footnote-11142771
+Node: Using Internal File Ops1142911
+Ref: Using Internal File Ops-Footnote-11145294
+Node: Extension Samples1145568
+Node: Extension Sample File Functions1147097
+Node: Extension Sample Fnmatch1154746
+Node: Extension Sample Fork1156233
+Node: Extension Sample Inplace1157451
+Node: Extension Sample Ord1161077
+Node: Extension Sample Readdir1161913
+Ref: table-readdir-file-types1162802
+Node: Extension Sample Revout1163869
+Node: Extension Sample Rev2way1164458
+Node: Extension Sample Read write array1165198
+Node: Extension Sample Readfile1167140
+Node: Extension Sample Time1168235
+Node: Extension Sample API Tests1169987
+Node: gawkextlib1170479
+Node: Extension summary1173397
+Node: Extension Exercises1177099
+Node: Language History1178341
+Node: V7/SVR3.11179997
+Node: SVR41182149
+Node: POSIX1183583
+Node: BTL1184964
+Node: POSIX/GNU1185693
+Node: Feature History1191471
+Node: Common Extensions1207790
+Node: Ranges and Locales1209073
+Ref: Ranges and Locales-Footnote-11213689
+Ref: Ranges and Locales-Footnote-21213716
+Ref: Ranges and Locales-Footnote-31213951
+Node: Contributors1214174
+Node: History summary1220171
+Node: Installation1221551
+Node: Gawk Distribution1222495
+Node: Getting1222979
+Node: Extracting1223942
+Node: Distribution contents1225580
+Node: Unix Installation1232060
+Node: Quick Installation1232742
+Node: Shell Startup Files1235156
+Node: Additional Configuration Options1236245
+Node: Configuration Philosophy1238560
+Node: Non-Unix Installation1240929
+Node: PC Installation1241389
+Node: PC Binary Installation1242227
+Node: PC Compiling1242662
+Node: PC Using1243779
+Node: Cygwin1247332
+Node: MSYS1248556
+Node: VMS Installation1249158
+Node: VMS Compilation1249949
+Ref: VMS Compilation-Footnote-11251178
+Node: VMS Dynamic Extensions1251236
+Node: VMS Installation Details1252921
+Node: VMS Running1255174
+Node: VMS GNV1259453
+Node: VMS Old Gawk1260188
+Node: Bugs1260659
+Node: Bug address1261322
+Node: Usenet1264304
+Node: Maintainers1265308
+Node: Other Versions1266493
+Node: Installation summary1273581
+Node: Notes1274790
+Node: Compatibility Mode1275584
+Node: Additions1276366
+Node: Accessing The Source1277291
+Node: Adding Code1278728
+Node: New Ports1284947
+Node: Derived Files1289322
+Ref: Derived Files-Footnote-11294982
+Ref: Derived Files-Footnote-21295017
+Ref: Derived Files-Footnote-31295615
+Node: Future Extensions1295729
+Node: Implementation Limitations1296387
+Node: Extension Design1297597
+Node: Old Extension Problems1298741
+Ref: Old Extension Problems-Footnote-11300259
+Node: Extension New Mechanism Goals1300316
+Ref: Extension New Mechanism Goals-Footnote-11303680
+Node: Extension Other Design Decisions1303869
+Node: Extension Future Growth1305982
+Node: Notes summary1306588
+Node: Basic Concepts1307746
+Node: Basic High Level1308427
+Ref: figure-general-flow1308709
+Ref: figure-process-flow1309394
+Ref: Basic High Level-Footnote-11312695
+Node: Basic Data Typing1312880
+Node: Glossary1316208
+Node: Copying1348093
+Node: GNU Free Documentation License1385636
+Node: Index1410756

End Tag Table
diff --git a/doc/gawk.texi b/doc/gawk.texi
index e4d02059..664f9e70 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
@@ -8400,7 +8402,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})
@@ -10059,7 +10061,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
@@ -18295,7 +18297,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.
@@ -33642,21 +33644,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
@@ -33825,6 +33815,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
@@ -33946,6 +33937,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 d784d386..92098829 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
@@ -7953,7 +7955,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})
@@ -9612,7 +9614,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
@@ -17520,7 +17522,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.
@@ -32608,21 +32610,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
@@ -32791,6 +32781,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
@@ -32912,6 +32903,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 ea83b282..f2c5d0f5 100644
--- a/eval.c
+++ b/eval.c
@@ -24,10 +24,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;
@@ -1520,18 +1518,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();
@@ -1539,12 +1536,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 56427bab..5df5d5ac 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 cf53bbdd..df5c46ba 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 0e7be208..f02086e0 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 *