summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArnold D. Robbins <arnold@skeeve.com>2018-07-19 20:58:12 +0300
committerArnold D. Robbins <arnold@skeeve.com>2018-07-19 20:58:12 +0300
commita0b5e4a1d9f13433728fc2ee4128beedbe919b5e (patch)
tree7727b43745467c637d93516106707b45dd7cdc23
parent52e6f76e7c0199cf5ae64e4b23698884cc245912 (diff)
downloadgawk-dead-branches/revamp-scalar-comparisons.tar.gz
Make scalar comparisons match doubles for NaN and INF.dead-branches/revamp-scalar-comparisons
-rw-r--r--ChangeLog10
-rw-r--r--doc/ChangeLog5
-rw-r--r--doc/gawk.info1211
-rw-r--r--doc/gawk.texi72
-rw-r--r--doc/gawktexi.in72
-rw-r--r--eval.c152
-rw-r--r--helpers/ChangeLog4
-rwxr-xr-xhelpers/gen-float-table.c62
-rw-r--r--helpers/gen-table.awk59
-rw-r--r--interpret.h12
10 files changed, 1065 insertions, 594 deletions
diff --git a/ChangeLog b/ChangeLog
index 11b398fa..72866a1d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2018-07-19 Arnold D. Robbins <arnold@skeeve.com>
+
+ Revamp scalar comparisons to be like hardware doubles.
+
+ * eval.c (mpg_cmp_scalars): New routine.
+ (cmp_scalars): Change return type to bool. Rework code to take
+ NaNs and INFs and type of comparison into account. Call mpg_cmp_scalars
+ if necessary.
+ * interpret.h (r_interpret): Change calls to cmp_scalars().
+
2018-07-13 Arnold D. Robbins <arnold@skeeve.com>
* builtin.c (format_nan_inf): New function to generate +nan, -nan,
diff --git a/doc/ChangeLog b/doc/ChangeLog
index a8d885db..10032499 100644
--- a/doc/ChangeLog
+++ b/doc/ChangeLog
@@ -1,3 +1,8 @@
+2018-07-19 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in (IEEE 754 Special Values): New subsubsection on
+ NaNs and INFs.
+
2018-07-10 Arnold D. Robbins <arnold@skeeve.com>
* gawktexi.in (Control Letters): Add a note about output of NaN and
diff --git a/doc/gawk.info b/doc/gawk.info
index f9219634..9ea649cf 100644
--- a/doc/gawk.info
+++ b/doc/gawk.info
@@ -293,6 +293,7 @@ in (a) below. A copy of the license is included in the section entitled
strings with '<', etc.
* Variable Typing:: String type versus numeric type.
* Comparison Operators:: The comparison operators.
+* IEEE 754 Special Values:: Comparing IEEE 754 Special Floating-Point Values and Regular Numbers.
* POSIX String Comparison:: String comparison with POSIX rules.
* Boolean Ops:: Combining comparison expressions using
boolean operators '||' ("or"),
@@ -8693,6 +8694,7 @@ variables are typed, and how 'awk' compares variables.
* Variable Typing:: String type versus numeric type.
* Comparison Operators:: The comparison operators.
+* IEEE 754 Special Values:: Comparing IEEE 754 Special Floating-Point Values and Regular Numbers.
* POSIX String Comparison:: String comparison with POSIX rules.

@@ -8864,7 +8866,7 @@ program text comprise a string constant. The following examples print
thing.

-File: gawk.info, Node: Comparison Operators, Next: POSIX String Comparison, Prev: Variable Typing, Up: Typing and Comparison
+File: gawk.info, Node: Comparison Operators, Next: IEEE 754 Special Values, Prev: Variable Typing, Up: Typing and Comparison
6.3.2.2 Comparison Operators
............................
@@ -8977,9 +8979,57 @@ expression:
Constant Regexps::, where this is discussed in more detail.

-File: gawk.info, Node: POSIX String Comparison, Prev: Comparison Operators, Up: Typing and Comparison
+File: gawk.info, Node: IEEE 754 Special Values, Next: POSIX String Comparison, Prev: Comparison Operators, Up: Typing and Comparison
-6.3.2.3 String Comparison Based on Locale Collating Order
+6.3.2.3 Comparing IEEE 754 Special Floating-Point Values and Regular Numbers
+............................................................................
+
+Modern computing platforms use floating-point arithmatic as defined by
+the IEEE 754 standard (*FIXME: web link or two here*). Besides regular
+numbers, like -57 and 42, the standard defines two "special" values:
+"Infinity", and "Not-A-Number". (The latter is usally referred to as a
+"NaN".) These special values come in both positive and negative flavors.
+
+ Infinity values are easy to understand: negative infinity is smaller
+than any other possible negative value, and postive infinity is greater
+than any other possible positive value.
+
+ NaN values are harder to comprehend. They represent impossible
+values. A canonical example is 'sqrt(-1)'. This value doesn't exist,
+so the result of calling 'sqrt(-1)' is a NaN.
+
+ When comparing infinity values with '<', '<=', and so on, the results
+make sense. But when comparing NaN values, things are more surprising.
+In particular, _the only comparison that returns true for a NaN is_
+'!='. Every other comparison returns false. Most surprising of all, is
+that if you have two NaN values, they do *not* compare equal! They are
+not equal to each other, even if obtained in the same way. Consider
+this file, 'nan.awk':
+
+ BEGIN {
+ nan1 = sqrt(-1)
+ nan2 = sqrt(-1)
+ print nan1, nan2
+ print "nan1 == nan2 -->", (nan1 == nan2)
+ print "nan1 != nan2 -->", (nan1 != nan2)
+ }
+
+Here is what happens when it's run:
+
+ $ gawk -f nan.awk
+ -| gawk: x.awk:2: warning: sqrt: called with negative argument -1
+ -| gawk: x.awk:3: warning: sqrt: called with negative argument -1
+ -| -nan -nan
+ -| nan1 == nan2 --> 0
+ -| nan1 != nan2 --> 1
+
+ In short, remember that computer arithmetic is _not_ the same as
+paper-and-pencil arithmetic!
+
+
+File: gawk.info, Node: POSIX String Comparison, Prev: IEEE 754 Special Values, Up: Typing and Comparison
+
+6.3.2.4 String Comparison Based on Locale Collating Order
.........................................................
The POSIX standard used to say that all string comparisons are performed
@@ -36052,582 +36102,583 @@ Index

Tag Table:
Node: Top1200
-Node: Foreword343399
-Node: Foreword447841
-Node: Preface49373
-Ref: Preface-Footnote-152232
-Ref: Preface-Footnote-252339
-Ref: Preface-Footnote-352573
-Node: History52715
-Node: Names55067
-Ref: Names-Footnote-156161
-Node: This Manual56308
-Ref: This Manual-Footnote-162793
-Node: Conventions62893
-Node: Manual History65248
-Ref: Manual History-Footnote-168245
-Ref: Manual History-Footnote-268286
-Node: How To Contribute68360
-Node: Acknowledgments69286
-Node: Getting Started74194
-Node: Running gawk76633
-Node: One-shot77823
-Node: Read Terminal79086
-Node: Long81079
-Node: Executable Scripts82592
-Ref: Executable Scripts-Footnote-185387
-Node: Comments85490
-Node: Quoting87974
-Node: DOS Quoting93491
-Node: Sample Data Files95547
-Node: Very Simple98142
-Node: Two Rules103044
-Node: More Complex104929
-Node: Statements/Lines107795
-Ref: Statements/Lines-Footnote-1112254
-Node: Other Features112519
-Node: When113455
-Ref: When-Footnote-1115209
-Node: Intro Summary115274
-Node: Invoking Gawk116158
-Node: Command Line117672
-Node: Options118470
-Ref: Options-Footnote-1135032
-Ref: Options-Footnote-2135263
-Node: Other Arguments135288
-Node: Naming Standard Input138235
-Node: Environment Variables139328
-Node: AWKPATH Variable139886
-Ref: AWKPATH Variable-Footnote-1143298
-Ref: AWKPATH Variable-Footnote-2143332
-Node: AWKLIBPATH Variable143593
-Node: Other Environment Variables145251
-Node: Exit Status149072
-Node: Include Files149749
-Node: Loading Shared Libraries153274
-Node: Obsolete154702
-Node: Undocumented155394
-Node: Invoking Summary155691
-Node: Regexp157351
-Node: Regexp Usage158805
-Node: Escape Sequences160842
-Node: Regexp Operators167074
-Ref: Regexp Operators-Footnote-1174490
-Ref: Regexp Operators-Footnote-2174637
-Node: Bracket Expressions174735
-Ref: table-char-classes177211
-Node: Leftmost Longest180616
-Node: Computed Regexps181919
-Node: GNU Regexp Operators185346
-Node: Case-sensitivity189025
-Ref: Case-sensitivity-Footnote-1191912
-Ref: Case-sensitivity-Footnote-2192147
-Node: Regexp Summary192255
-Node: Reading Files193721
-Node: Records195990
-Node: awk split records197065
-Node: gawk split records202340
-Ref: gawk split records-Footnote-1206926
-Node: Fields206963
-Node: Nonconstant Fields209704
-Ref: Nonconstant Fields-Footnote-1211940
-Node: Changing Fields212144
-Node: Field Separators218072
-Node: Default Field Splitting220770
-Node: Regexp Field Splitting221888
-Node: Single Character Fields225241
-Node: Command Line Field Separator226301
-Node: Full Line Fields229519
-Ref: Full Line Fields-Footnote-1231041
-Ref: Full Line Fields-Footnote-2231087
-Node: Field Splitting Summary231188
-Node: Constant Size233262
-Node: Fixed width data233994
-Node: Skipping intervening237461
-Node: Allowing trailing data238259
-Node: Fields with fixed data239296
-Node: Splitting By Content240814
-Ref: Splitting By Content-Footnote-1244464
-Node: Testing field creation244627
-Node: Multiple Line246252
-Ref: Multiple Line-Footnote-1252136
-Node: Getline252315
-Node: Plain Getline254784
-Node: Getline/Variable257425
-Node: Getline/File258576
-Node: Getline/Variable/File259964
-Ref: Getline/Variable/File-Footnote-1261569
-Node: Getline/Pipe261657
-Node: Getline/Variable/Pipe264364
-Node: Getline/Coprocess265499
-Node: Getline/Variable/Coprocess266766
-Node: Getline Notes267508
-Node: Getline Summary270305
-Ref: table-getline-variants270729
-Node: Read Timeout271477
-Ref: Read Timeout-Footnote-1275383
-Node: Retrying Input275441
-Node: Command-line directories276640
-Node: Input Summary277546
-Node: Input Exercises280718
-Node: Printing281446
-Node: Print283280
-Node: Print Examples284737
-Node: Output Separators287517
-Node: OFMT289534
-Node: Printf290890
-Node: Basic Printf291675
-Node: Control Letters293249
-Node: Format Modifiers298376
-Node: Printf Examples304391
-Node: Redirection306877
-Node: Special FD313718
-Ref: Special FD-Footnote-1316886
-Node: Special Files316960
-Node: Other Inherited Files317577
-Node: Special Network318578
-Node: Special Caveats319438
-Node: Close Files And Pipes320387
-Ref: table-close-pipe-return-values327294
-Ref: Close Files And Pipes-Footnote-1328107
-Ref: Close Files And Pipes-Footnote-2328255
-Node: Nonfatal328407
-Node: Output Summary330745
-Node: Output Exercises331967
-Node: Expressions332646
-Node: Values333834
-Node: Constants334512
-Node: Scalar Constants335203
-Ref: Scalar Constants-Footnote-1336067
-Node: Nondecimal-numbers336317
-Node: Regexp Constants339318
-Node: Using Constant Regexps339844
-Node: Standard Regexp Constants340466
-Node: Strong Regexp Constants343654
-Node: Variables346612
-Node: Using Variables347269
-Node: Assignment Options349179
-Node: Conversion351052
-Node: Strings And Numbers351576
-Ref: Strings And Numbers-Footnote-1354639
-Node: Locale influences conversions354748
-Ref: table-locale-affects357506
-Node: All Operators358124
-Node: Arithmetic Ops358753
-Node: Concatenation361259
-Ref: Concatenation-Footnote-1364106
-Node: Assignment Ops364213
-Ref: table-assign-ops369204
-Node: Increment Ops370517
-Node: Truth Values and Conditions373977
-Node: Truth Values375051
-Node: Typing and Comparison376099
-Node: Variable Typing376919
-Ref: Variable Typing-Footnote-1383382
-Ref: Variable Typing-Footnote-2383454
-Node: Comparison Operators383531
-Ref: table-relational-ops383950
-Node: POSIX String Comparison387445
-Ref: POSIX String Comparison-Footnote-1389140
-Ref: POSIX String Comparison-Footnote-2389279
-Node: Boolean Ops389363
-Ref: Boolean Ops-Footnote-1393845
-Node: Conditional Exp393937
-Node: Function Calls395673
-Node: Precedence399550
-Node: Locales403209
-Node: Expressions Summary404841
-Node: Patterns and Actions407414
-Node: Pattern Overview408534
-Node: Regexp Patterns410211
-Node: Expression Patterns410753
-Node: Ranges414534
-Node: BEGIN/END417642
-Node: Using BEGIN/END418403
-Ref: Using BEGIN/END-Footnote-1421139
-Node: I/O And BEGIN/END421245
-Node: BEGINFILE/ENDFILE423559
-Node: Empty426472
-Node: Using Shell Variables426789
-Node: Action Overview429063
-Node: Statements431388
-Node: If Statement433236
-Node: While Statement434731
-Node: Do Statement436759
-Node: For Statement437907
-Node: Switch Statement441078
-Node: Break Statement443464
-Node: Continue Statement445556
-Node: Next Statement447383
-Node: Nextfile Statement449766
-Node: Exit Statement452418
-Node: Built-in Variables454821
-Node: User-modified455954
-Node: Auto-set463721
-Ref: Auto-set-Footnote-1480023
-Ref: Auto-set-Footnote-2480229
-Node: ARGC and ARGV480285
-Node: Pattern Action Summary484498
-Node: Arrays486928
-Node: Array Basics488257
-Node: Array Intro489101
-Ref: figure-array-elements491076
-Ref: Array Intro-Footnote-1493780
-Node: Reference to Elements493908
-Node: Assigning Elements496372
-Node: Array Example496863
-Node: Scanning an Array498622
-Node: Controlling Scanning501644
-Ref: Controlling Scanning-Footnote-1507043
-Node: Numeric Array Subscripts507359
-Node: Uninitialized Subscripts509543
-Node: Delete511162
-Ref: Delete-Footnote-1513914
-Node: Multidimensional513971
-Node: Multiscanning517066
-Node: Arrays of Arrays518657
-Node: Arrays Summary523424
-Node: Functions525517
-Node: Built-in526555
-Node: Calling Built-in527636
-Node: Numeric Functions529632
-Ref: Numeric Functions-Footnote-1533660
-Ref: Numeric Functions-Footnote-2534017
-Ref: Numeric Functions-Footnote-3534065
-Node: String Functions534337
-Ref: String Functions-Footnote-1558046
-Ref: String Functions-Footnote-2558174
-Ref: String Functions-Footnote-3558422
-Node: Gory Details558509
-Ref: table-sub-escapes560300
-Ref: table-sub-proposed561819
-Ref: table-posix-sub563182
-Ref: table-gensub-escapes564723
-Ref: Gory Details-Footnote-1565546
-Node: I/O Functions565700
-Ref: table-system-return-values572168
-Ref: I/O Functions-Footnote-1574148
-Ref: I/O Functions-Footnote-2574296
-Node: Time Functions574416
-Ref: Time Functions-Footnote-1585087
-Ref: Time Functions-Footnote-2585155
-Ref: Time Functions-Footnote-3585313
-Ref: Time Functions-Footnote-4585424
-Ref: Time Functions-Footnote-5585536
-Ref: Time Functions-Footnote-6585763
-Node: Bitwise Functions586029
-Ref: table-bitwise-ops586623
-Ref: Bitwise Functions-Footnote-1592686
-Ref: Bitwise Functions-Footnote-2592859
-Node: Type Functions593050
-Node: I18N Functions595801
-Node: User-defined597452
-Node: Definition Syntax598257
-Ref: Definition Syntax-Footnote-1603944
-Node: Function Example604015
-Ref: Function Example-Footnote-1606937
-Node: Function Caveats606959
-Node: Calling A Function607477
-Node: Variable Scope608435
-Node: Pass By Value/Reference611429
-Node: Return Statement614928
-Node: Dynamic Typing617907
-Node: Indirect Calls618837
-Ref: Indirect Calls-Footnote-1629089
-Node: Functions Summary629217
-Node: Library Functions631922
-Ref: Library Functions-Footnote-1635529
-Ref: Library Functions-Footnote-2635672
-Node: Library Names635843
-Ref: Library Names-Footnote-1639303
-Ref: Library Names-Footnote-2639526
-Node: General Functions639612
-Node: Strtonum Function640715
-Node: Assert Function643737
-Node: Round Function647063
-Node: Cliff Random Function648603
-Node: Ordinal Functions649619
-Ref: Ordinal Functions-Footnote-1652682
-Ref: Ordinal Functions-Footnote-2652934
-Node: Join Function653144
-Ref: Join Function-Footnote-1654914
-Node: Getlocaltime Function655114
-Node: Readfile Function658856
-Node: Shell Quoting660833
-Node: Data File Management662234
-Node: Filetrans Function662866
-Node: Rewind Function666962
-Node: File Checking668872
-Ref: File Checking-Footnote-1670206
-Node: Empty Files670407
-Node: Ignoring Assigns672386
-Node: Getopt Function673936
-Ref: Getopt Function-Footnote-1685405
-Node: Passwd Functions685605
-Ref: Passwd Functions-Footnote-1694444
-Node: Group Functions694532
-Ref: Group Functions-Footnote-1702430
-Node: Walking Arrays702637
-Node: Library Functions Summary705645
-Node: Library Exercises707051
-Node: Sample Programs707516
-Node: Running Examples708286
-Node: Clones709014
-Node: Cut Program710238
-Node: Egrep Program720167
-Ref: Egrep Program-Footnote-1727679
-Node: Id Program727789
-Node: Split Program731469
-Ref: Split Program-Footnote-1734927
-Node: Tee Program735056
-Node: Uniq Program737846
-Node: Wc Program745272
-Ref: Wc Program-Footnote-1749527
-Node: Miscellaneous Programs749621
-Node: Dupword Program750834
-Node: Alarm Program752864
-Node: Translate Program757719
-Ref: Translate Program-Footnote-1762284
-Node: Labels Program762554
-Ref: Labels Program-Footnote-1765905
-Node: Word Sorting765989
-Node: History Sorting770061
-Node: Extract Program771896
-Node: Simple Sed779950
-Node: Igawk Program783024
-Ref: Igawk Program-Footnote-1797355
-Ref: Igawk Program-Footnote-2797557
-Ref: Igawk Program-Footnote-3797679
-Node: Anagram Program797794
-Node: Signature Program800856
-Node: Programs Summary802103
-Node: Programs Exercises803317
-Ref: Programs Exercises-Footnote-1807446
-Node: Advanced Features807537
-Node: Nondecimal Data809527
-Node: Array Sorting811118
-Node: Controlling Array Traversal811818
-Ref: Controlling Array Traversal-Footnote-1820186
-Node: Array Sorting Functions820304
-Ref: Array Sorting Functions-Footnote-1825395
-Node: Two-way I/O825591
-Ref: Two-way I/O-Footnote-1832143
-Ref: Two-way I/O-Footnote-2832330
-Node: TCP/IP Networking832412
-Node: Profiling835530
-Ref: Profiling-Footnote-1844202
-Node: Advanced Features Summary844525
-Node: Internationalization846369
-Node: I18N and L10N847849
-Node: Explaining gettext848536
-Ref: Explaining gettext-Footnote-1854428
-Ref: Explaining gettext-Footnote-2854613
-Node: Programmer i18n854778
-Ref: Programmer i18n-Footnote-1859727
-Node: Translator i18n859776
-Node: String Extraction860570
-Ref: String Extraction-Footnote-1861702
-Node: Printf Ordering861788
-Ref: Printf Ordering-Footnote-1864574
-Node: I18N Portability864638
-Ref: I18N Portability-Footnote-1867094
-Node: I18N Example867157
-Ref: I18N Example-Footnote-1869963
-Node: Gawk I18N870036
-Node: I18N Summary870681
-Node: Debugger872022
-Node: Debugging873045
-Node: Debugging Concepts873486
-Node: Debugging Terms875295
-Node: Awk Debugging877870
-Node: Sample Debugging Session878776
-Node: Debugger Invocation879310
-Node: Finding The Bug880696
-Node: List of Debugger Commands887174
-Node: Breakpoint Control888507
-Node: Debugger Execution Control892201
-Node: Viewing And Changing Data895563
-Node: Execution Stack898937
-Node: Debugger Info900574
-Node: Miscellaneous Debugger Commands904645
-Node: Readline Support909707
-Node: Limitations910603
-Node: Debugging Summary912712
-Node: Arbitrary Precision Arithmetic913991
-Node: Computer Arithmetic915476
-Ref: table-numeric-ranges919242
-Ref: table-floating-point-ranges919735
-Ref: Computer Arithmetic-Footnote-1920393
-Node: Math Definitions920450
-Ref: table-ieee-formats923766
-Ref: Math Definitions-Footnote-1924369
-Node: MPFR features924474
-Node: FP Math Caution926192
-Ref: FP Math Caution-Footnote-1927264
-Node: Inexactness of computations927633
-Node: Inexact representation928593
-Node: Comparing FP Values929953
-Node: Errors accumulate931035
-Node: Getting Accuracy932468
-Node: Try To Round935178
-Node: Setting precision936077
-Ref: table-predefined-precision-strings936774
-Node: Setting the rounding mode938604
-Ref: table-gawk-rounding-modes938978
-Ref: Setting the rounding mode-Footnote-1942909
-Node: Arbitrary Precision Integers943088
-Ref: Arbitrary Precision Integers-Footnote-1946263
-Node: Checking for MPFR946412
-Node: POSIX Floating Point Problems947886
-Ref: POSIX Floating Point Problems-Footnote-1952171
-Node: Floating point summary952209
-Node: Dynamic Extensions954399
-Node: Extension Intro955952
-Node: Plugin License957218
-Node: Extension Mechanism Outline958015
-Ref: figure-load-extension958454
-Ref: figure-register-new-function960019
-Ref: figure-call-new-function961111
-Node: Extension API Description963173
-Node: Extension API Functions Introduction964815
-Node: General Data Types970355
-Ref: General Data Types-Footnote-1978716
-Node: Memory Allocation Functions979015
-Ref: Memory Allocation Functions-Footnote-1983225
-Node: Constructor Functions983324
-Node: Registration Functions986910
-Node: Extension Functions987595
-Node: Exit Callback Functions992810
-Node: Extension Version String994060
-Node: Input Parsers994723
-Node: Output Wrappers1007444
-Node: Two-way processors1011956
-Node: Printing Messages1014221
-Ref: Printing Messages-Footnote-11015392
-Node: Updating ERRNO1015545
-Node: Requesting Values1016284
-Ref: table-value-types-returned1017021
-Node: Accessing Parameters1017957
-Node: Symbol Table Access1019192
-Node: Symbol table by name1019704
-Node: Symbol table by cookie1021493
-Ref: Symbol table by cookie-Footnote-11025678
-Node: Cached values1025742
-Ref: Cached values-Footnote-11029278
-Node: Array Manipulation1029431
-Ref: Array Manipulation-Footnote-11030522
-Node: Array Data Types1030559
-Ref: Array Data Types-Footnote-11033217
-Node: Array Functions1033309
-Node: Flattening Arrays1037807
-Node: Creating Arrays1044783
-Node: Redirection API1049550
-Node: Extension API Variables1052383
-Node: Extension Versioning1053094
-Ref: gawk-api-version1053523
-Node: Extension GMP/MPFR Versioning1055254
-Node: Extension API Informational Variables1056882
-Node: Extension API Boilerplate1057955
-Node: Changes from API V11061929
-Node: Finding Extensions1063501
-Node: Extension Example1064060
-Node: Internal File Description1064858
-Node: Internal File Ops1068938
-Ref: Internal File Ops-Footnote-11080288
-Node: Using Internal File Ops1080428
-Ref: Using Internal File Ops-Footnote-11082811
-Node: Extension Samples1083085
-Node: Extension Sample File Functions1084614
-Node: Extension Sample Fnmatch1092263
-Node: Extension Sample Fork1093750
-Node: Extension Sample Inplace1094968
-Node: Extension Sample Ord1098185
-Node: Extension Sample Readdir1099021
-Ref: table-readdir-file-types1099910
-Node: Extension Sample Revout1100715
-Node: Extension Sample Rev2way1101304
-Node: Extension Sample Read write array1102044
-Node: Extension Sample Readfile1103986
-Node: Extension Sample Time1105081
-Node: Extension Sample API Tests1106429
-Node: gawkextlib1106921
-Node: Extension summary1109839
-Node: Extension Exercises1113541
-Node: Language History1115039
-Node: V7/SVR3.11116695
-Node: SVR41118847
-Node: POSIX1120281
-Node: BTL1121661
-Node: POSIX/GNU1122390
-Node: Feature History1128168
-Node: Common Extensions1144027
-Node: Ranges and Locales1145310
-Ref: Ranges and Locales-Footnote-11149926
-Ref: Ranges and Locales-Footnote-21149953
-Ref: Ranges and Locales-Footnote-31150188
-Node: Contributors1150409
-Node: History summary1156354
-Node: Installation1157734
-Node: Gawk Distribution1158678
-Node: Getting1159162
-Node: Extracting1160125
-Node: Distribution contents1161763
-Node: Unix Installation1168243
-Node: Quick Installation1168925
-Node: Shell Startup Files1171339
-Node: Additional Configuration Options1172428
-Node: Configuration Philosophy1174593
-Node: Non-Unix Installation1176962
-Node: PC Installation1177422
-Node: PC Binary Installation1178260
-Node: PC Compiling1178695
-Node: PC Using1179812
-Node: Cygwin1183027
-Node: MSYS1184126
-Node: VMS Installation1184627
-Node: VMS Compilation1185418
-Ref: VMS Compilation-Footnote-11186647
-Node: VMS Dynamic Extensions1186705
-Node: VMS Installation Details1188390
-Node: VMS Running1190643
-Node: VMS GNV1194922
-Node: VMS Old Gawk1195657
-Node: Bugs1196128
-Node: Bug address1196791
-Node: Usenet1199583
-Node: Maintainers1200360
-Node: Other Versions1201621
-Node: Installation summary1208383
-Node: Notes1209585
-Node: Compatibility Mode1210450
-Node: Additions1211232
-Node: Accessing The Source1212157
-Node: Adding Code1213594
-Node: New Ports1219813
-Node: Derived Files1224301
-Ref: Derived Files-Footnote-11229947
-Ref: Derived Files-Footnote-21229982
-Ref: Derived Files-Footnote-31230580
-Node: Future Extensions1230694
-Node: Implementation Limitations1231352
-Node: Extension Design1232535
-Node: Old Extension Problems1233689
-Ref: Old Extension Problems-Footnote-11235207
-Node: Extension New Mechanism Goals1235264
-Ref: Extension New Mechanism Goals-Footnote-11238628
-Node: Extension Other Design Decisions1238817
-Node: Extension Future Growth1240930
-Node: Old Extension Mechanism1241766
-Node: Notes summary1243529
-Node: Basic Concepts1244711
-Node: Basic High Level1245392
-Ref: figure-general-flow1245674
-Ref: figure-process-flow1246359
-Ref: Basic High Level-Footnote-11249660
-Node: Basic Data Typing1249845
-Node: Glossary1253173
-Node: Copying1285011
-Node: GNU Free Documentation License1322554
-Node: Index1347674
+Node: Foreword343509
+Node: Foreword447951
+Node: Preface49483
+Ref: Preface-Footnote-152342
+Ref: Preface-Footnote-252449
+Ref: Preface-Footnote-352683
+Node: History52825
+Node: Names55177
+Ref: Names-Footnote-156271
+Node: This Manual56418
+Ref: This Manual-Footnote-162903
+Node: Conventions63003
+Node: Manual History65358
+Ref: Manual History-Footnote-168355
+Ref: Manual History-Footnote-268396
+Node: How To Contribute68470
+Node: Acknowledgments69396
+Node: Getting Started74304
+Node: Running gawk76743
+Node: One-shot77933
+Node: Read Terminal79196
+Node: Long81189
+Node: Executable Scripts82702
+Ref: Executable Scripts-Footnote-185497
+Node: Comments85600
+Node: Quoting88084
+Node: DOS Quoting93601
+Node: Sample Data Files95657
+Node: Very Simple98252
+Node: Two Rules103154
+Node: More Complex105039
+Node: Statements/Lines107905
+Ref: Statements/Lines-Footnote-1112364
+Node: Other Features112629
+Node: When113565
+Ref: When-Footnote-1115319
+Node: Intro Summary115384
+Node: Invoking Gawk116268
+Node: Command Line117782
+Node: Options118580
+Ref: Options-Footnote-1135142
+Ref: Options-Footnote-2135373
+Node: Other Arguments135398
+Node: Naming Standard Input138345
+Node: Environment Variables139438
+Node: AWKPATH Variable139996
+Ref: AWKPATH Variable-Footnote-1143408
+Ref: AWKPATH Variable-Footnote-2143442
+Node: AWKLIBPATH Variable143703
+Node: Other Environment Variables145361
+Node: Exit Status149182
+Node: Include Files149859
+Node: Loading Shared Libraries153384
+Node: Obsolete154812
+Node: Undocumented155504
+Node: Invoking Summary155801
+Node: Regexp157461
+Node: Regexp Usage158915
+Node: Escape Sequences160952
+Node: Regexp Operators167184
+Ref: Regexp Operators-Footnote-1174600
+Ref: Regexp Operators-Footnote-2174747
+Node: Bracket Expressions174845
+Ref: table-char-classes177321
+Node: Leftmost Longest180726
+Node: Computed Regexps182029
+Node: GNU Regexp Operators185456
+Node: Case-sensitivity189135
+Ref: Case-sensitivity-Footnote-1192022
+Ref: Case-sensitivity-Footnote-2192257
+Node: Regexp Summary192365
+Node: Reading Files193831
+Node: Records196100
+Node: awk split records197175
+Node: gawk split records202450
+Ref: gawk split records-Footnote-1207036
+Node: Fields207073
+Node: Nonconstant Fields209814
+Ref: Nonconstant Fields-Footnote-1212050
+Node: Changing Fields212254
+Node: Field Separators218182
+Node: Default Field Splitting220880
+Node: Regexp Field Splitting221998
+Node: Single Character Fields225351
+Node: Command Line Field Separator226411
+Node: Full Line Fields229629
+Ref: Full Line Fields-Footnote-1231151
+Ref: Full Line Fields-Footnote-2231197
+Node: Field Splitting Summary231298
+Node: Constant Size233372
+Node: Fixed width data234104
+Node: Skipping intervening237571
+Node: Allowing trailing data238369
+Node: Fields with fixed data239406
+Node: Splitting By Content240924
+Ref: Splitting By Content-Footnote-1244574
+Node: Testing field creation244737
+Node: Multiple Line246362
+Ref: Multiple Line-Footnote-1252246
+Node: Getline252425
+Node: Plain Getline254894
+Node: Getline/Variable257535
+Node: Getline/File258686
+Node: Getline/Variable/File260074
+Ref: Getline/Variable/File-Footnote-1261679
+Node: Getline/Pipe261767
+Node: Getline/Variable/Pipe264474
+Node: Getline/Coprocess265609
+Node: Getline/Variable/Coprocess266876
+Node: Getline Notes267618
+Node: Getline Summary270415
+Ref: table-getline-variants270839
+Node: Read Timeout271587
+Ref: Read Timeout-Footnote-1275493
+Node: Retrying Input275551
+Node: Command-line directories276750
+Node: Input Summary277656
+Node: Input Exercises280828
+Node: Printing281556
+Node: Print283390
+Node: Print Examples284847
+Node: Output Separators287627
+Node: OFMT289644
+Node: Printf291000
+Node: Basic Printf291785
+Node: Control Letters293359
+Node: Format Modifiers298486
+Node: Printf Examples304501
+Node: Redirection306987
+Node: Special FD313828
+Ref: Special FD-Footnote-1316996
+Node: Special Files317070
+Node: Other Inherited Files317687
+Node: Special Network318688
+Node: Special Caveats319548
+Node: Close Files And Pipes320497
+Ref: table-close-pipe-return-values327404
+Ref: Close Files And Pipes-Footnote-1328217
+Ref: Close Files And Pipes-Footnote-2328365
+Node: Nonfatal328517
+Node: Output Summary330855
+Node: Output Exercises332077
+Node: Expressions332756
+Node: Values333944
+Node: Constants334622
+Node: Scalar Constants335313
+Ref: Scalar Constants-Footnote-1336177
+Node: Nondecimal-numbers336427
+Node: Regexp Constants339428
+Node: Using Constant Regexps339954
+Node: Standard Regexp Constants340576
+Node: Strong Regexp Constants343764
+Node: Variables346722
+Node: Using Variables347379
+Node: Assignment Options349289
+Node: Conversion351162
+Node: Strings And Numbers351686
+Ref: Strings And Numbers-Footnote-1354749
+Node: Locale influences conversions354858
+Ref: table-locale-affects357616
+Node: All Operators358234
+Node: Arithmetic Ops358863
+Node: Concatenation361369
+Ref: Concatenation-Footnote-1364216
+Node: Assignment Ops364323
+Ref: table-assign-ops369314
+Node: Increment Ops370627
+Node: Truth Values and Conditions374087
+Node: Truth Values375161
+Node: Typing and Comparison376209
+Node: Variable Typing377131
+Ref: Variable Typing-Footnote-1383594
+Ref: Variable Typing-Footnote-2383666
+Node: Comparison Operators383743
+Ref: table-relational-ops384162
+Node: IEEE 754 Special Values387657
+Node: POSIX String Comparison389700
+Ref: POSIX String Comparison-Footnote-1391398
+Ref: POSIX String Comparison-Footnote-2391537
+Node: Boolean Ops391621
+Ref: Boolean Ops-Footnote-1396103
+Node: Conditional Exp396195
+Node: Function Calls397931
+Node: Precedence401808
+Node: Locales405467
+Node: Expressions Summary407099
+Node: Patterns and Actions409672
+Node: Pattern Overview410792
+Node: Regexp Patterns412469
+Node: Expression Patterns413011
+Node: Ranges416792
+Node: BEGIN/END419900
+Node: Using BEGIN/END420661
+Ref: Using BEGIN/END-Footnote-1423397
+Node: I/O And BEGIN/END423503
+Node: BEGINFILE/ENDFILE425817
+Node: Empty428730
+Node: Using Shell Variables429047
+Node: Action Overview431321
+Node: Statements433646
+Node: If Statement435494
+Node: While Statement436989
+Node: Do Statement439017
+Node: For Statement440165
+Node: Switch Statement443336
+Node: Break Statement445722
+Node: Continue Statement447814
+Node: Next Statement449641
+Node: Nextfile Statement452024
+Node: Exit Statement454676
+Node: Built-in Variables457079
+Node: User-modified458212
+Node: Auto-set465979
+Ref: Auto-set-Footnote-1482281
+Ref: Auto-set-Footnote-2482487
+Node: ARGC and ARGV482543
+Node: Pattern Action Summary486756
+Node: Arrays489186
+Node: Array Basics490515
+Node: Array Intro491359
+Ref: figure-array-elements493334
+Ref: Array Intro-Footnote-1496038
+Node: Reference to Elements496166
+Node: Assigning Elements498630
+Node: Array Example499121
+Node: Scanning an Array500880
+Node: Controlling Scanning503902
+Ref: Controlling Scanning-Footnote-1509301
+Node: Numeric Array Subscripts509617
+Node: Uninitialized Subscripts511801
+Node: Delete513420
+Ref: Delete-Footnote-1516172
+Node: Multidimensional516229
+Node: Multiscanning519324
+Node: Arrays of Arrays520915
+Node: Arrays Summary525682
+Node: Functions527775
+Node: Built-in528813
+Node: Calling Built-in529894
+Node: Numeric Functions531890
+Ref: Numeric Functions-Footnote-1535918
+Ref: Numeric Functions-Footnote-2536275
+Ref: Numeric Functions-Footnote-3536323
+Node: String Functions536595
+Ref: String Functions-Footnote-1560304
+Ref: String Functions-Footnote-2560432
+Ref: String Functions-Footnote-3560680
+Node: Gory Details560767
+Ref: table-sub-escapes562558
+Ref: table-sub-proposed564077
+Ref: table-posix-sub565440
+Ref: table-gensub-escapes566981
+Ref: Gory Details-Footnote-1567804
+Node: I/O Functions567958
+Ref: table-system-return-values574426
+Ref: I/O Functions-Footnote-1576406
+Ref: I/O Functions-Footnote-2576554
+Node: Time Functions576674
+Ref: Time Functions-Footnote-1587345
+Ref: Time Functions-Footnote-2587413
+Ref: Time Functions-Footnote-3587571
+Ref: Time Functions-Footnote-4587682
+Ref: Time Functions-Footnote-5587794
+Ref: Time Functions-Footnote-6588021
+Node: Bitwise Functions588287
+Ref: table-bitwise-ops588881
+Ref: Bitwise Functions-Footnote-1594944
+Ref: Bitwise Functions-Footnote-2595117
+Node: Type Functions595308
+Node: I18N Functions598059
+Node: User-defined599710
+Node: Definition Syntax600515
+Ref: Definition Syntax-Footnote-1606202
+Node: Function Example606273
+Ref: Function Example-Footnote-1609195
+Node: Function Caveats609217
+Node: Calling A Function609735
+Node: Variable Scope610693
+Node: Pass By Value/Reference613687
+Node: Return Statement617186
+Node: Dynamic Typing620165
+Node: Indirect Calls621095
+Ref: Indirect Calls-Footnote-1631347
+Node: Functions Summary631475
+Node: Library Functions634180
+Ref: Library Functions-Footnote-1637787
+Ref: Library Functions-Footnote-2637930
+Node: Library Names638101
+Ref: Library Names-Footnote-1641561
+Ref: Library Names-Footnote-2641784
+Node: General Functions641870
+Node: Strtonum Function642973
+Node: Assert Function645995
+Node: Round Function649321
+Node: Cliff Random Function650861
+Node: Ordinal Functions651877
+Ref: Ordinal Functions-Footnote-1654940
+Ref: Ordinal Functions-Footnote-2655192
+Node: Join Function655402
+Ref: Join Function-Footnote-1657172
+Node: Getlocaltime Function657372
+Node: Readfile Function661114
+Node: Shell Quoting663091
+Node: Data File Management664492
+Node: Filetrans Function665124
+Node: Rewind Function669220
+Node: File Checking671130
+Ref: File Checking-Footnote-1672464
+Node: Empty Files672665
+Node: Ignoring Assigns674644
+Node: Getopt Function676194
+Ref: Getopt Function-Footnote-1687663
+Node: Passwd Functions687863
+Ref: Passwd Functions-Footnote-1696702
+Node: Group Functions696790
+Ref: Group Functions-Footnote-1704688
+Node: Walking Arrays704895
+Node: Library Functions Summary707903
+Node: Library Exercises709309
+Node: Sample Programs709774
+Node: Running Examples710544
+Node: Clones711272
+Node: Cut Program712496
+Node: Egrep Program722425
+Ref: Egrep Program-Footnote-1729937
+Node: Id Program730047
+Node: Split Program733727
+Ref: Split Program-Footnote-1737185
+Node: Tee Program737314
+Node: Uniq Program740104
+Node: Wc Program747530
+Ref: Wc Program-Footnote-1751785
+Node: Miscellaneous Programs751879
+Node: Dupword Program753092
+Node: Alarm Program755122
+Node: Translate Program759977
+Ref: Translate Program-Footnote-1764542
+Node: Labels Program764812
+Ref: Labels Program-Footnote-1768163
+Node: Word Sorting768247
+Node: History Sorting772319
+Node: Extract Program774154
+Node: Simple Sed782208
+Node: Igawk Program785282
+Ref: Igawk Program-Footnote-1799613
+Ref: Igawk Program-Footnote-2799815
+Ref: Igawk Program-Footnote-3799937
+Node: Anagram Program800052
+Node: Signature Program803114
+Node: Programs Summary804361
+Node: Programs Exercises805575
+Ref: Programs Exercises-Footnote-1809704
+Node: Advanced Features809795
+Node: Nondecimal Data811785
+Node: Array Sorting813376
+Node: Controlling Array Traversal814076
+Ref: Controlling Array Traversal-Footnote-1822444
+Node: Array Sorting Functions822562
+Ref: Array Sorting Functions-Footnote-1827653
+Node: Two-way I/O827849
+Ref: Two-way I/O-Footnote-1834401
+Ref: Two-way I/O-Footnote-2834588
+Node: TCP/IP Networking834670
+Node: Profiling837788
+Ref: Profiling-Footnote-1846460
+Node: Advanced Features Summary846783
+Node: Internationalization848627
+Node: I18N and L10N850107
+Node: Explaining gettext850794
+Ref: Explaining gettext-Footnote-1856686
+Ref: Explaining gettext-Footnote-2856871
+Node: Programmer i18n857036
+Ref: Programmer i18n-Footnote-1861985
+Node: Translator i18n862034
+Node: String Extraction862828
+Ref: String Extraction-Footnote-1863960
+Node: Printf Ordering864046
+Ref: Printf Ordering-Footnote-1866832
+Node: I18N Portability866896
+Ref: I18N Portability-Footnote-1869352
+Node: I18N Example869415
+Ref: I18N Example-Footnote-1872221
+Node: Gawk I18N872294
+Node: I18N Summary872939
+Node: Debugger874280
+Node: Debugging875303
+Node: Debugging Concepts875744
+Node: Debugging Terms877553
+Node: Awk Debugging880128
+Node: Sample Debugging Session881034
+Node: Debugger Invocation881568
+Node: Finding The Bug882954
+Node: List of Debugger Commands889432
+Node: Breakpoint Control890765
+Node: Debugger Execution Control894459
+Node: Viewing And Changing Data897821
+Node: Execution Stack901195
+Node: Debugger Info902832
+Node: Miscellaneous Debugger Commands906903
+Node: Readline Support911965
+Node: Limitations912861
+Node: Debugging Summary914970
+Node: Arbitrary Precision Arithmetic916249
+Node: Computer Arithmetic917734
+Ref: table-numeric-ranges921500
+Ref: table-floating-point-ranges921993
+Ref: Computer Arithmetic-Footnote-1922651
+Node: Math Definitions922708
+Ref: table-ieee-formats926024
+Ref: Math Definitions-Footnote-1926627
+Node: MPFR features926732
+Node: FP Math Caution928450
+Ref: FP Math Caution-Footnote-1929522
+Node: Inexactness of computations929891
+Node: Inexact representation930851
+Node: Comparing FP Values932211
+Node: Errors accumulate933293
+Node: Getting Accuracy934726
+Node: Try To Round937436
+Node: Setting precision938335
+Ref: table-predefined-precision-strings939032
+Node: Setting the rounding mode940862
+Ref: table-gawk-rounding-modes941236
+Ref: Setting the rounding mode-Footnote-1945167
+Node: Arbitrary Precision Integers945346
+Ref: Arbitrary Precision Integers-Footnote-1948521
+Node: Checking for MPFR948670
+Node: POSIX Floating Point Problems950144
+Ref: POSIX Floating Point Problems-Footnote-1954429
+Node: Floating point summary954467
+Node: Dynamic Extensions956657
+Node: Extension Intro958210
+Node: Plugin License959476
+Node: Extension Mechanism Outline960273
+Ref: figure-load-extension960712
+Ref: figure-register-new-function962277
+Ref: figure-call-new-function963369
+Node: Extension API Description965431
+Node: Extension API Functions Introduction967073
+Node: General Data Types972613
+Ref: General Data Types-Footnote-1980974
+Node: Memory Allocation Functions981273
+Ref: Memory Allocation Functions-Footnote-1985483
+Node: Constructor Functions985582
+Node: Registration Functions989168
+Node: Extension Functions989853
+Node: Exit Callback Functions995068
+Node: Extension Version String996318
+Node: Input Parsers996981
+Node: Output Wrappers1009702
+Node: Two-way processors1014214
+Node: Printing Messages1016479
+Ref: Printing Messages-Footnote-11017650
+Node: Updating ERRNO1017803
+Node: Requesting Values1018542
+Ref: table-value-types-returned1019279
+Node: Accessing Parameters1020215
+Node: Symbol Table Access1021450
+Node: Symbol table by name1021962
+Node: Symbol table by cookie1023751
+Ref: Symbol table by cookie-Footnote-11027936
+Node: Cached values1028000
+Ref: Cached values-Footnote-11031536
+Node: Array Manipulation1031689
+Ref: Array Manipulation-Footnote-11032780
+Node: Array Data Types1032817
+Ref: Array Data Types-Footnote-11035475
+Node: Array Functions1035567
+Node: Flattening Arrays1040065
+Node: Creating Arrays1047041
+Node: Redirection API1051808
+Node: Extension API Variables1054641
+Node: Extension Versioning1055352
+Ref: gawk-api-version1055781
+Node: Extension GMP/MPFR Versioning1057512
+Node: Extension API Informational Variables1059140
+Node: Extension API Boilerplate1060213
+Node: Changes from API V11064187
+Node: Finding Extensions1065759
+Node: Extension Example1066318
+Node: Internal File Description1067116
+Node: Internal File Ops1071196
+Ref: Internal File Ops-Footnote-11082546
+Node: Using Internal File Ops1082686
+Ref: Using Internal File Ops-Footnote-11085069
+Node: Extension Samples1085343
+Node: Extension Sample File Functions1086872
+Node: Extension Sample Fnmatch1094521
+Node: Extension Sample Fork1096008
+Node: Extension Sample Inplace1097226
+Node: Extension Sample Ord1100443
+Node: Extension Sample Readdir1101279
+Ref: table-readdir-file-types1102168
+Node: Extension Sample Revout1102973
+Node: Extension Sample Rev2way1103562
+Node: Extension Sample Read write array1104302
+Node: Extension Sample Readfile1106244
+Node: Extension Sample Time1107339
+Node: Extension Sample API Tests1108687
+Node: gawkextlib1109179
+Node: Extension summary1112097
+Node: Extension Exercises1115799
+Node: Language History1117297
+Node: V7/SVR3.11118953
+Node: SVR41121105
+Node: POSIX1122539
+Node: BTL1123919
+Node: POSIX/GNU1124648
+Node: Feature History1130426
+Node: Common Extensions1146285
+Node: Ranges and Locales1147568
+Ref: Ranges and Locales-Footnote-11152184
+Ref: Ranges and Locales-Footnote-21152211
+Ref: Ranges and Locales-Footnote-31152446
+Node: Contributors1152667
+Node: History summary1158612
+Node: Installation1159992
+Node: Gawk Distribution1160936
+Node: Getting1161420
+Node: Extracting1162383
+Node: Distribution contents1164021
+Node: Unix Installation1170501
+Node: Quick Installation1171183
+Node: Shell Startup Files1173597
+Node: Additional Configuration Options1174686
+Node: Configuration Philosophy1176851
+Node: Non-Unix Installation1179220
+Node: PC Installation1179680
+Node: PC Binary Installation1180518
+Node: PC Compiling1180953
+Node: PC Using1182070
+Node: Cygwin1185285
+Node: MSYS1186384
+Node: VMS Installation1186885
+Node: VMS Compilation1187676
+Ref: VMS Compilation-Footnote-11188905
+Node: VMS Dynamic Extensions1188963
+Node: VMS Installation Details1190648
+Node: VMS Running1192901
+Node: VMS GNV1197180
+Node: VMS Old Gawk1197915
+Node: Bugs1198386
+Node: Bug address1199049
+Node: Usenet1201841
+Node: Maintainers1202618
+Node: Other Versions1203879
+Node: Installation summary1210641
+Node: Notes1211843
+Node: Compatibility Mode1212708
+Node: Additions1213490
+Node: Accessing The Source1214415
+Node: Adding Code1215852
+Node: New Ports1222071
+Node: Derived Files1226559
+Ref: Derived Files-Footnote-11232205
+Ref: Derived Files-Footnote-21232240
+Ref: Derived Files-Footnote-31232838
+Node: Future Extensions1232952
+Node: Implementation Limitations1233610
+Node: Extension Design1234793
+Node: Old Extension Problems1235947
+Ref: Old Extension Problems-Footnote-11237465
+Node: Extension New Mechanism Goals1237522
+Ref: Extension New Mechanism Goals-Footnote-11240886
+Node: Extension Other Design Decisions1241075
+Node: Extension Future Growth1243188
+Node: Old Extension Mechanism1244024
+Node: Notes summary1245787
+Node: Basic Concepts1246969
+Node: Basic High Level1247650
+Ref: figure-general-flow1247932
+Ref: figure-process-flow1248617
+Ref: Basic High Level-Footnote-11251918
+Node: Basic Data Typing1252103
+Node: Glossary1255431
+Node: Copying1287269
+Node: GNU Free Documentation License1324812
+Node: Index1349932

End Tag Table
diff --git a/doc/gawk.texi b/doc/gawk.texi
index 5081449a..74e8bbb2 100644
--- a/doc/gawk.texi
+++ b/doc/gawk.texi
@@ -665,6 +665,7 @@ particular records in a file and perform operations upon them.
strings with @samp{<}, etc.
* Variable Typing:: String type versus numeric type.
* Comparison Operators:: The comparison operators.
+* IEEE 754 Special Values:: Comparing IEEE 754 Special Floating-Point Values and Regular Numbers.
* POSIX String Comparison:: String comparison with POSIX rules.
* Boolean Ops:: Combining comparison expressions using
boolean operators @samp{||} (``or''),
@@ -12560,6 +12561,7 @@ compares variables.
@menu
* Variable Typing:: String type versus numeric type.
* Comparison Operators:: The comparison operators.
+* IEEE 754 Special Values:: Comparing IEEE 754 Special Floating-Point Values and Regular Numbers.
* POSIX String Comparison:: String comparison with POSIX rules.
@end menu
@@ -13016,6 +13018,76 @@ One special place where @code{/foo/} is @emph{not} an abbreviation for
@xref{Using Constant Regexps},
where this is discussed in more detail.
+@c FIXME: Add indexing here and in other places in the doc.
+@node IEEE 754 Special Values
+@subsubsection Comparing IEEE 754 Special Floating-Point Values and Regular Numbers
+
+Modern computing platforms use floating-point arithmatic as defined by the
+IEEE 754 standard (@strong{FIXME: web link or two here}). Besides regular
+numbers, like @minus{}57 and 42, the standard defines two ``special''
+values: @dfn{Infinity}, and @dfn{Not-A-Number}. (The latter is usally
+referred to as a @dfn{NaN}.) These special values come in both positive
+and negative flavors.
+
+Infinity values are easy to understand: negative infinity is smaller
+than any other possible negative value, and postive infinity is greater
+than any other possible positive value.
+
+NaN values are harder to comprehend. They represent impossible values.
+A canonical example is
+@iftex
+@math{\sqrt{-1}}.
+@end iftex
+@ifdocbook
+@docbook
+&radic;&minus;1.
+@end docbook
+@end ifdocbook
+@ifhtml
+@html
+<span style="white-space: nowrap; font-size:larger">
+&radic;<span style="text-decoration:overline;">&nbsp;&minus;1&nbsp;</span>.
+</span>
+@end html
+@end ifhtml
+@ifinfo
+@samp{sqrt(-1)}.
+@end ifinfo
+This value doesn't exist, so the result of calling @samp{sqrt(-1)} is a NaN.
+
+When comparing infinity values with @code{<}, @code{<=}, and so on,
+the results make sense. But when comparing NaN values, things are
+more surprising. In particular, @emph{the only comparison that returns
+true for a NaN is} @code{!=}. Every other comparison returns false.
+Most surprising of all, is that if you have two NaN values, they do
+@strong{not} compare equal! They are not equal to each other, even if
+obtained in the same way. Consider this file, @file{nan.awk}:
+
+@example
+BEGIN @{
+ nan1 = sqrt(-1)
+ nan2 = sqrt(-1)
+ print nan1, nan2
+ print "nan1 == nan2 -->", (nan1 == nan2)
+ print "nan1 != nan2 -->", (nan1 != nan2)
+@}
+@end example
+
+@noindent
+Here is what happens when it's run:
+
+@example
+$ @kbd{gawk -f nan.awk}
+@print{} gawk: x.awk:2: warning: sqrt: called with negative argument -1
+@print{} gawk: x.awk:3: warning: sqrt: called with negative argument -1
+@print{} -nan -nan
+@print{} nan1 == nan2 --> 0
+@print{} nan1 != nan2 --> 1
+@end example
+
+In short, remember that computer arithmetic is @emph{not} the same
+as paper-and-pencil arithmetic!
+
@node POSIX String Comparison
@subsubsection String Comparison Based on Locale Collating Order
diff --git a/doc/gawktexi.in b/doc/gawktexi.in
index dff0e18c..0f5895dc 100644
--- a/doc/gawktexi.in
+++ b/doc/gawktexi.in
@@ -660,6 +660,7 @@ particular records in a file and perform operations upon them.
strings with @samp{<}, etc.
* Variable Typing:: String type versus numeric type.
* Comparison Operators:: The comparison operators.
+* IEEE 754 Special Values:: Comparing IEEE 754 Special Floating-Point Values and Regular Numbers.
* POSIX String Comparison:: String comparison with POSIX rules.
* Boolean Ops:: Combining comparison expressions using
boolean operators @samp{||} (``or''),
@@ -11878,6 +11879,7 @@ compares variables.
@menu
* Variable Typing:: String type versus numeric type.
* Comparison Operators:: The comparison operators.
+* IEEE 754 Special Values:: Comparing IEEE 754 Special Floating-Point Values and Regular Numbers.
* POSIX String Comparison:: String comparison with POSIX rules.
@end menu
@@ -12334,6 +12336,76 @@ One special place where @code{/foo/} is @emph{not} an abbreviation for
@xref{Using Constant Regexps},
where this is discussed in more detail.
+@c FIXME: Add indexing here and in other places in the doc.
+@node IEEE 754 Special Values
+@subsubsection Comparing IEEE 754 Special Floating-Point Values and Regular Numbers
+
+Modern computing platforms use floating-point arithmatic as defined by the
+IEEE 754 standard (@strong{FIXME: web link or two here}). Besides regular
+numbers, like @minus{}57 and 42, the standard defines two ``special''
+values: @dfn{Infinity}, and @dfn{Not-A-Number}. (The latter is usally
+referred to as a @dfn{NaN}.) These special values come in both positive
+and negative flavors.
+
+Infinity values are easy to understand: negative infinity is smaller
+than any other possible negative value, and postive infinity is greater
+than any other possible positive value.
+
+NaN values are harder to comprehend. They represent impossible values.
+A canonical example is
+@iftex
+@math{\sqrt{-1}}.
+@end iftex
+@ifdocbook
+@docbook
+&radic;&minus;1.
+@end docbook
+@end ifdocbook
+@ifhtml
+@html
+<span style="white-space: nowrap; font-size:larger">
+&radic;<span style="text-decoration:overline;">&nbsp;&minus;1&nbsp;</span>.
+</span>
+@end html
+@end ifhtml
+@ifinfo
+@samp{sqrt(-1)}.
+@end ifinfo
+This value doesn't exist, so the result of calling @samp{sqrt(-1)} is a NaN.
+
+When comparing infinity values with @code{<}, @code{<=}, and so on,
+the results make sense. But when comparing NaN values, things are
+more surprising. In particular, @emph{the only comparison that returns
+true for a NaN is} @code{!=}. Every other comparison returns false.
+Most surprising of all, is that if you have two NaN values, they do
+@strong{not} compare equal! They are not equal to each other, even if
+obtained in the same way. Consider this file, @file{nan.awk}:
+
+@example
+BEGIN @{
+ nan1 = sqrt(-1)
+ nan2 = sqrt(-1)
+ print nan1, nan2
+ print "nan1 == nan2 -->", (nan1 == nan2)
+ print "nan1 != nan2 -->", (nan1 != nan2)
+@}
+@end example
+
+@noindent
+Here is what happens when it's run:
+
+@example
+$ @kbd{gawk -f nan.awk}
+@print{} gawk: x.awk:2: warning: sqrt: called with negative argument -1
+@print{} gawk: x.awk:3: warning: sqrt: called with negative argument -1
+@print{} -nan -nan
+@print{} nan1 == nan2 --> 0
+@print{} nan1 != nan2 --> 1
+@end example
+
+In short, remember that computer arithmetic is @emph{not} the same
+as paper-and-pencil arithmetic!
+
@node POSIX String Comparison
@subsubsection String Comparison Based on Locale Collating Order
diff --git a/eval.c b/eval.c
index 34ba174c..9ed088be 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;
@@ -1489,13 +1487,84 @@ eval_condition(NODE *t)
}
typedef enum {
- SCALAR_EQ_NEQ,
- SCALAR_RELATIONAL
+ SCALAR_EQ,
+ SCALAR_NE,
+ SCALAR_LT,
+ SCALAR_LE,
+ SCALAR_GT,
+ SCALAR_GE,
} scalar_cmp_t;
+#ifdef HAVE_MPFR
+/* mpg_cmp_scalars -- compare two MPG / MPFR nodes on the stack */
+
+static inline bool
+mpg_cmp_scalars(NODE *t1, NODE *t2, scalar_cmp_t comparison_type)
+{
+ // Do regular comparison of mpg numbers
+
+ int ret = 0;
+ if (is_mpg_float(t1)) {
+ if (mpfr_nan_p(t1->mpg_numbr))
+ return (comparison_type == SCALAR_NE); // true for !=, false for everything else
+ else if (is_mpg_float(t2)) {
+ if (mpfr_nan_p(t2->mpg_numbr))
+ return (comparison_type == SCALAR_NE); // true for !=, false for everything else
+ ret = mpfr_cmp(t1->mpg_numbr, t2->mpg_numbr);
+ // fall through to switch
+ } else if (is_mpg_integer(t2)) {
+ ret = mpfr_cmp_z(t1->mpg_numbr, t2->mpg_i);
+ // fall through to switch
+ } else
+ assert(false);
+ } else if (is_mpg_float(t2)) {
+ if (mpfr_nan_p(t2->mpg_numbr))
+ return (comparison_type == SCALAR_NE); // true for !=, false for everything else
+ ret = mpfr_cmp_z(t2->mpg_numbr, t1->mpg_i);
+ // fall through to switch
+ } else if (is_mpg_integer(t1)) {
+ ret = mpz_cmp(t1->mpg_i, t2->mpg_i);
+ // fall through to switch
+ } else {
+ // t1 and t2 are AWKNUMs
+ ret = cmp_awknums(t1, t2);
+ // fall through to switch
+ }
+
+ bool result = false;
+ switch (comparison_type) {
+ case SCALAR_EQ:
+ result = (ret == 0);
+ break;
+ case SCALAR_NE:
+ result = (ret != 0);
+ break;
+ case SCALAR_LT:
+ result = (ret < 0);
+ break;
+ case SCALAR_LE:
+ result = (ret <= 0);
+ break;
+ case SCALAR_GT:
+ result = (ret > 0);
+ break;
+ case SCALAR_GE:
+ result = (ret >= 0);
+ break;
+ default:
+ fatal(_("mpg_cmp_scalars: bad value for comparison_type: %d"),
+ comparison_type);
+ break;
+ }
+
+ return result;
+
+}
+#endif
+
/* cmp_scalars -- compare two nodes on the stack */
-static inline int
+static inline bool
cmp_scalars(scalar_cmp_t comparison_type)
{
NODE *t1, *t2;
@@ -1507,10 +1576,77 @@ 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);
+
+
+ fixtype(t1);
+ fixtype(t2);
+
+ bool result = false;
+#ifdef HAVE_MPFR
+ if (is_mpg_number(t1) || is_mpg_number(t2)) {
+ result = mpg_cmp_scalars(t1, t2, comparison_type);
+ } else
+#endif
+ if (isnan(t1->numbr) || isnan(t2->numbr))
+ result = (comparison_type == SCALAR_NE); // true for !=, false for everything else
+ else if (isinf(t1->numbr) || isinf(t2->numbr)) {
+ switch (comparison_type) {
+ case SCALAR_EQ:
+ result = (t1->numbr == t2->numbr);
+ break;
+ case SCALAR_NE:
+ result = (t1->numbr != t2->numbr);
+ break;
+ case SCALAR_LT:
+ result = (t1->numbr < t2->numbr);
+ break;
+ case SCALAR_LE:
+ result = (t1->numbr <= t2->numbr);
+ break;
+ case SCALAR_GT:
+ result = (t1->numbr > t2->numbr);
+ break;
+ case SCALAR_GE:
+ result = (t1->numbr >= t2->numbr);
+ break;
+ default:
+ fatal(_("cmp_scalars: bad value for comparison_type: %d"),
+ comparison_type);
+ break;
+ }
+ } else {
+ di = cmp_nodes(t1, t2,
+ comparison_type == SCALAR_EQ || comparison_type == SCALAR_NE);
+
+ switch (comparison_type) {
+ case SCALAR_EQ:
+ result = (di == 0);
+ break;
+ case SCALAR_NE:
+ result = (di != 0);
+ break;
+ case SCALAR_LT:
+ result = (di < 0);
+ break;
+ case SCALAR_LE:
+ result = (di <= 0);
+ break;
+ case SCALAR_GT:
+ result = (di > 0);
+ break;
+ case SCALAR_GE:
+ result = (di >= 0);
+ break;
+ default:
+ fatal(_("cmp_scalars: bad value for comparison_type: %d"),
+ comparison_type);
+ break;
+ }
+ }
+
DEREF(t1);
DEREF(t2);
- return di;
+ return result;
}
/* op_assign --- assignment operators excluding = */
diff --git a/helpers/ChangeLog b/helpers/ChangeLog
index d54de869..2c07b068 100644
--- a/helpers/ChangeLog
+++ b/helpers/ChangeLog
@@ -1,3 +1,7 @@
+2018-07-19 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gen-float-table.c, gen-table.awk: New files.
+
2018-02-25 Arnold D. Robbins <arnold@skeeve.com>
* 4.2.1: Release tar ball made.
diff --git a/helpers/gen-float-table.c b/helpers/gen-float-table.c
new file mode 100755
index 00000000..95985422
--- /dev/null
+++ b/helpers/gen-float-table.c
@@ -0,0 +1,62 @@
+#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/helpers/gen-table.awk b/helpers/gen-table.awk
new file mode 100644
index 00000000..6998ae0e
--- /dev/null
+++ b/helpers/gen-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]
+ result = @the_func(values[i], compare[j])
+ printf("%g %s %g -> %s\n",
+ values[i],
+ names[k],
+ compare[j],
+ result ? "true" : "false");
+ }
+ printf("\n");
+ }
+ }
+}
diff --git a/interpret.h b/interpret.h
index 8408a532..866bf7b7 100644
--- a/interpret.h
+++ b/interpret.h
@@ -459,37 +459,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_NE)];
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;