Commit | Line | Data |
---|---|---|
731d116a C |
1 | Right now, the numeric vs. string comparisons are screwed up in draft |
2 | 11.2. What prompted me to check it out was the note in gnu.bug.utils | |
3 | which observed that gawk was doing the comparison $1 == "000" | |
4 | numerically. I think that we can agree that intuitively, this should | |
5 | be done as a string comparison. Version 2.13.2 of gawk follows the | |
6 | current POSIX draft. Following is how I (now) think this | |
7 | stuff should be done. | |
8 | ||
9 | 1. A numeric literal or the result of a numeric operation has the NUMERIC | |
10 | attribute. | |
11 | ||
12 | 2. A string literal or the result of a string operation has the STRING | |
13 | attribute. | |
14 | ||
15 | 3. Fields, getline input, FILENAME, ARGV elements, ENVIRON elements and the | |
16 | elements of an array created by split() that are numeric strings | |
17 | have the STRNUM attribute. Otherwise, they have the STRING attribute. | |
18 | Uninitialized variables also have the STRNUM attribute. | |
19 | ||
20 | 4. Attributes propagate across assignments, but are not changed by | |
21 | any use. (Although a use may cause the entity to acquire an additional | |
22 | value such that it has both a numeric and string value -- this leaves the | |
23 | attribute unchanged.) | |
24 | ||
25 | When two operands are compared, either string comparison or numeric comparison | |
26 | may be used, depending on the attributes of the operands, according to the | |
27 | following (symmetric) matrix: | |
28 | ||
29 | +---------------------------------------------- | |
30 | | STRING NUMERIC STRNUM | |
31 | --------+---------------------------------------------- | |
32 | | | |
33 | STRING | string string string | |
34 | | | |
35 | NUMERIC | string numeric numeric | |
36 | | | |
37 | STRNUM | string numeric numeric | |
38 | --------+---------------------------------------------- | |
39 | ||
40 | So, the following program should print all OKs. | |
41 | ||
42 | echo '0e2 0a 0 0b | |
43 | 0e2 0a 0 0b' | | |
44 | $AWK ' | |
45 | NR == 1 { | |
46 | num = 0 | |
47 | str = "0e2" | |
48 | ||
49 | print ++test ": " ( (str == "0e2") ? "OK" : "OOPS" ) | |
50 | print ++test ": " ( ("0e2" != 0) ? "OK" : "OOPS" ) | |
51 | print ++test ": " ( ("0" != $2) ? "OK" : "OOPS" ) | |
52 | print ++test ": " ( ("0e2" == $1) ? "OK" : "OOPS" ) | |
53 | ||
54 | print ++test ": " ( (0 == "0") ? "OK" : "OOPS" ) | |
55 | print ++test ": " ( (0 == num) ? "OK" : "OOPS" ) | |
56 | print ++test ": " ( (0 != $2) ? "OK" : "OOPS" ) | |
57 | print ++test ": " ( (0 == $1) ? "OK" : "OOPS" ) | |
58 | ||
59 | print ++test ": " ( ($1 != "0") ? "OK" : "OOPS" ) | |
60 | print ++test ": " ( ($1 == num) ? "OK" : "OOPS" ) | |
61 | print ++test ": " ( ($2 != 0) ? "OK" : "OOPS" ) | |
62 | print ++test ": " ( ($2 != $1) ? "OK" : "OOPS" ) | |
63 | print ++test ": " ( ($3 == 0) ? "OK" : "OOPS" ) | |
64 | print ++test ": " ( ($3 == $1) ? "OK" : "OOPS" ) | |
65 | print ++test ": " ( ($2 != $4) ? "OK" : "OOPS" ) # 15 | |
66 | } | |
67 | { | |
68 | a = "+2" | |
69 | b = 2 | |
70 | if (NR % 2) | |
71 | c = a + b | |
72 | print ++test ": " ( (a != b) ? "OK" : "OOPS" ) # 16 and 22 | |
73 | ||
74 | d = "2a" | |
75 | b = 2 | |
76 | if (NR % 2) | |
77 | c = d + b | |
78 | print ++test ": " ( (d != b) ? "OK" : "OOPS" ) | |
79 | ||
80 | print ++test ": " ( (d + 0 == b) ? "OK" : "OOPS" ) | |
81 | ||
82 | e = "2" | |
83 | print ++test ": " ( (e == b "") ? "OK" : "OOPS" ) | |
84 | ||
85 | a = "2.13" | |
86 | print ++test ": " ( (a == 2.13) ? "OK" : "OOPS" ) | |
87 | ||
88 | a = "2.130000" | |
89 | print ++test ": " ( (a != 2.13) ? "OK" : "OOPS" ) | |
90 | ||
91 | if (NR == 2) { | |
92 | CONVFMT = "%.6f" | |
93 | print ++test ": " ( (a == 2.13) ? "OK" : "OOPS" ) | |
94 | } | |
95 | }' |