home *** CD-ROM | disk | FTP | other *** search
- Right now, the numeric vs. string comparisons are screwed up in draft
- 11.2. What prompted me to check it out was the note in gnu.bug.utils
- which observed that gawk was doing the comparison $1 == "000"
- numerically. I think that we can agree that intuitively, this should
- be done as a string comparison. Version 2.13.2 of gawk follows the
- current POSIX draft. Following is how I (now) think this
- stuff should be done.
-
- 1. A numeric literal or the result of a numeric operation has the NUMERIC
- attribute.
-
- 2. A string literal or the result of a string operation has the STRING
- attribute.
-
- 3. Fields, getline input, FILENAME, ARGV elements, ENVIRON elements and the
- elements of an array created by split() that are numeric strings
- have the STRNUM attribute. Otherwise, they have the STRING attribute.
- Uninitialized variables also have the STRNUM attribute.
-
- 4. Attributes propagate across assignments, but are not changed by
- any use. (Although a use may cause the entity to acquire an additional
- value such that it has both a numeric and string value -- this leaves the
- attribute unchanged.)
-
- When two operands are compared, either string comparison or numeric comparison
- may be used, depending on the attributes of the operands, according to the
- following (symmetric) matrix:
-
- +----------------------------------------------
- | STRING NUMERIC STRNUM
- --------+----------------------------------------------
- |
- STRING | string string string
- |
- NUMERIC | string numeric numeric
- |
- STRNUM | string numeric numeric
- --------+----------------------------------------------
-
- So, the following program should print all OKs.
-
- echo '0e2 0a 0 0b
- 0e2 0a 0 0b' |
- $AWK '
- NR == 1 {
- num = 0
- str = "0e2"
-
- print ++test ": " ( (str == "0e2") ? "OK" : "OOPS" )
- print ++test ": " ( ("0e2" != 0) ? "OK" : "OOPS" )
- print ++test ": " ( ("0" != $2) ? "OK" : "OOPS" )
- print ++test ": " ( ("0e2" == $1) ? "OK" : "OOPS" )
-
- print ++test ": " ( (0 == "0") ? "OK" : "OOPS" )
- print ++test ": " ( (0 == num) ? "OK" : "OOPS" )
- print ++test ": " ( (0 != $2) ? "OK" : "OOPS" )
- print ++test ": " ( (0 == $1) ? "OK" : "OOPS" )
-
- print ++test ": " ( ($1 != "0") ? "OK" : "OOPS" )
- print ++test ": " ( ($1 == num) ? "OK" : "OOPS" )
- print ++test ": " ( ($2 != 0) ? "OK" : "OOPS" )
- print ++test ": " ( ($2 != $1) ? "OK" : "OOPS" )
- print ++test ": " ( ($3 == 0) ? "OK" : "OOPS" )
- print ++test ": " ( ($3 == $1) ? "OK" : "OOPS" )
- print ++test ": " ( ($2 != $4) ? "OK" : "OOPS" ) # 15
- }
- {
- a = "+2"
- b = 2
- if (NR % 2)
- c = a + b
- print ++test ": " ( (a != b) ? "OK" : "OOPS" ) # 16 and 22
-
- d = "2a"
- b = 2
- if (NR % 2)
- c = d + b
- print ++test ": " ( (d != b) ? "OK" : "OOPS" )
-
- print ++test ": " ( (d + 0 == b) ? "OK" : "OOPS" )
-
- e = "2"
- print ++test ": " ( (e == b "") ? "OK" : "OOPS" )
-
- a = "2.13"
- print ++test ": " ( (a == 2.13) ? "OK" : "OOPS" )
-
- a = "2.130000"
- print ++test ": " ( (a != 2.13) ? "OK" : "OOPS" )
-
- if (NR == 2) {
- CONVFMT = "%.6f"
- print ++test ": " ( (a == 2.13) ? "OK" : "OOPS" )
- }
- }'
-