diff options
-rw-r--r-- | ChangeLog | 13 | ||||
-rw-r--r-- | NEWS | 8 | ||||
-rw-r--r-- | awk.h | 9 | ||||
-rw-r--r-- | awklib/eg/test-programs/gen-float-table.awk | 59 | ||||
-rw-r--r-- | awklib/eg/test-programs/gen-float-table.c | 60 | ||||
-rw-r--r-- | awklib/eg/test-programs/gen-float-table.py | 42 | ||||
-rw-r--r-- | builtin.c | 2 | ||||
-rw-r--r-- | doc/ChangeLog | 27 | ||||
-rw-r--r-- | doc/gawk.info | 1284 | ||||
-rw-r--r-- | doc/gawk.texi | 273 | ||||
-rw-r--r-- | doc/gawktexi.in | 273 | ||||
-rw-r--r-- | doc/it/ChangeLog | 4 | ||||
-rwxr-xr-x[-rw-r--r--] | doc/it/gawktexi.in | 308 | ||||
-rw-r--r-- | doc/wordlist | 2 | ||||
-rw-r--r-- | eval.c | 96 | ||||
-rw-r--r-- | interpret.h | 12 | ||||
-rw-r--r-- | mpfr.c | 44 | ||||
-rw-r--r-- | node.c | 3 |
18 files changed, 1802 insertions, 717 deletions
@@ -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. @@ -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 --------------------------- @@ -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("") @@ -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 @@ -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; @@ -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. @@ -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 * |