110 lines
3.5 KiB
Plaintext
110 lines
3.5 KiB
Plaintext
|
August 1995:
|
||
|
|
||
|
Although the published 1003.2 standard contained the incorrect
|
||
|
comparison rules of 11.2 draft as described below, no actual implementation
|
||
|
of awk (that I know of) actually used those rules.
|
||
|
|
||
|
A revision of the 1003.2 standard is in progress, and in the May 1995
|
||
|
draft, the rules were fixed (based on my submissions for interpretation
|
||
|
requests) to match the description given below. Thus, the next version
|
||
|
of the standard will have a correct description of the comparison
|
||
|
rules.
|
||
|
|
||
|
June 1992:
|
||
|
|
||
|
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" )
|
||
|
}
|
||
|
}'
|