diff options
author | Arnold D. Robbins <arnold@skeeve.com> | 2018-07-19 20:58:12 +0300 |
---|---|---|
committer | Arnold D. Robbins <arnold@skeeve.com> | 2018-07-19 20:58:12 +0300 |
commit | a0b5e4a1d9f13433728fc2ee4128beedbe919b5e (patch) | |
tree | 7727b43745467c637d93516106707b45dd7cdc23 | |
parent | 52e6f76e7c0199cf5ae64e4b23698884cc245912 (diff) | |
download | gawk-dead-branches/revamp-scalar-comparisons.tar.gz |
Make scalar comparisons match doubles for NaN and INF.dead-branches/revamp-scalar-comparisons
-rw-r--r-- | ChangeLog | 10 | ||||
-rw-r--r-- | doc/ChangeLog | 5 | ||||
-rw-r--r-- | doc/gawk.info | 1211 | ||||
-rw-r--r-- | doc/gawk.texi | 72 | ||||
-rw-r--r-- | doc/gawktexi.in | 72 | ||||
-rw-r--r-- | eval.c | 152 | ||||
-rw-r--r-- | helpers/ChangeLog | 4 | ||||
-rwxr-xr-x | helpers/gen-float-table.c | 62 | ||||
-rw-r--r-- | helpers/gen-table.awk | 59 | ||||
-rw-r--r-- | interpret.h | 12 |
10 files changed, 1065 insertions, 594 deletions
@@ -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 +√−1. +@end docbook +@end ifdocbook +@ifhtml +@html +<span style="white-space: nowrap; font-size:larger"> +√<span style="text-decoration:overline;"> −1 </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 +√−1. +@end docbook +@end ifdocbook +@ifhtml +@html +<span style="white-space: nowrap; font-size:larger"> +√<span style="text-decoration:overline;"> −1 </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 @@ -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; |