@DATABASE "ARB11"
@INDEX "ARB:Misc/Index.Text/Main"
@HELP "ARB:Misc/Help/Main"
@NODE "Main" "ARexx For Beginners - Article 11 - Comparison Operators"

@{B}@{U}@{JCENTER}AREXX FOR BEGINNERS

ARTICLE 11 - COMPARISON OPERATORS

BY FRANK BUNTON@{UB}@{UU}

@{" COPYRIGHT © FRANK P. BUNTON 1995-1998 " LINK "ARB:Misc/Read_Me_First!!/Copyright"}
@{JLEFT}

Before we start to look at the usage of IF...THEN...ELSE in conditional
statements we will need to look at "Comparison Operators". These can be
used in conjunction with the @{"Arithmetic Operators" LINK "ARB:Articles_01-10/09.Arithmetic_Operators/MAIN"} that we have already
talked about.

A full list of operators is contained in @{"Appendix B" LINK "ARB:Appendices/App-B_Operators/MAIN"} which covers Arithmetic,
Logical, Comparison and Concatenation operators.
@{JCENTER}

@{" Comparison Operators Available " LINK "Available"}
@{" Numeric Comparisons            " LINK "Numeric"}
@{" String Comparisons             " LINK "String"}
@{" Symbol Comparisons             " LINK "Symbol"}
@{" Exact Comparisons              " LINK "Exact"}


@{JCENTER}=== End of Text ===
@{JLEFT}
@ENDNODE

@NODE "Available" "Article 11 - Comparison Operators - Available"

@{B}@{U}@{JCENTER}COMPARISON OPERATORS AVAILABLE@{UB}@{UU}
@{JLEFT}
The full set of comparison operators is shown below. Where the operator
@{B}~@{UB} is used, it represents @{B}"NOT"@{UB} or the reverse of the operator that follows
it. Thus if = is equal, then ~= is not equal.

These operators can make both @{"numeric comparisons" LINK "Numeric"} and
@{"string comparisons" LINK "String"}.

@{U}Priority@{UU}  @{U}Operator@{UU}   @{U}Purpose                                         
@{UU}
   3         =       Equality
   3        ~=       Inequality
   3         ==      Exact Equality
   3        ~==      Exact Inequality
   3        >        Greater Than
   3        <        Less than
   3        >=       Greater than or equal to
   3        <=       Less than or equal to
   3        ~>       Not greater than (same as <= less than or equal to)
   3        ~<       Not less than (same as >= greater than or equal to)

As indicated above, all these operators have a @{"priority" LINK "ARB:Articles_01-10/09.Arithmetic_Operators/Priorities"} of 3.

@{B}Note@{UB} - in some programming languages:-

  >= is the same as =>
  <= is the same as =<

However, in ARexx you can @{B}not@{UB} use these alternatives! (I make this note
for the benefit of people who are used to using both alternatives.)

The use of these operators returns a @{"Boolean" LINK "ARB:Misc/Glossary/Boolean"} value of:-

   @{B}TRUE@{UB}   1       or       @{B}FALSE@{UB}   0

For example:-

  SAY 1 = 1     -->  1
  SAY 1 = 2     -->  0


@{JCENTER}=== End of Text ===
@{JLEFT}
@ENDNODE

@NODE "Numeric" "Article 11 - Comparison Operators - Numeric Comparisons"

@{B}@{U}@{JCENTER}NUMERIC COMPARISONS@{UB}@{UU}
@{JLEFT}
@{B}Numeric@{UB} comparisons are, to most people, straight forward. A number is
either equal to, greater than or less than, another number.

@{B}Numeric@{UB} comparisons evaluate the expressions being compared before making
the comparison to see if the statement is true or false. Thus you can
have things like:-

  24     ~= 24      --> False
  2  * 12 = 6 * 4   --> True
  48 / 2  = 25      --> False
  24 / 2  < 25      --> True

  N1 = 5 ; N2 = 7 ; N1 + 16 = N2 * 3   --> True

As indicated by the above line, we can have @{"symbol comparisons" LINK "Symbol"}.


@{JCENTER}=== End of Text ===
@{JLEFT}
@ENDNODE

@NODE "String" "Article 11 - Comparison Operators - String Comparisons"

@{B}@{U}@{JCENTER}STRING COMPARISONS@{UB}@{UU}
@{JLEFT}
@{B}String@{UB} comparisons are a bit harder to understand than @{"numeric" LINK "Numeric"}
comparisons.

They proceed on a character by character basis (starting at the @{B}left@{UB} end
of the string) based on the @{"ASCII" LINK "ARB:Misc/Glossary/ASCII"} values, or @{"code numbers" LINK "ARB:Appendices/App-C_ASCII_Codes/MAIN"}, of the
characters in the string.

I will not go into a full explanation here (double click on the above
highlighted areas to read more about it) but, briefly:-

* All upper case letters are @{B}less than@{UB} all lower case letters

   For example:-     'A' is less than 'a'
                     'Z' is less then 'a'

* Within upper or lower case, 'A' is less than 'B' which is less than 'C'
   and so on to 'Y' is less than 'Z'

   For example:-     'A' is less than 'B'
                     'a' is less than 'b'

* All numbers are less than all alphabetics.

   For example:-     '9' is less than 'A'

* If the first characters of each string are equal then the comparison
  continues on to the second character of each string.

  For example:-      'AA' is less than 'AB'

* In longer strings, the comparisons continue from left to right until
  an unequal character is found.

  For example:-      'abcdefGhij' is less than 'abcdefghij'
                     'This is me' is less than 'This is you'

In this way, the @{B}string@{UB} comparison give the appearance of being done on
alphabetical order but in actual fact they are done on numerical order
of ASCII codes.

Note that all the strings above are included in quotes. If you are comparing
strings then you @{B}must@{UB} put them in quotes!! As I have said before, characters
not in quotes are symbols, not strings!

To illustrate this,:-

  IF Ab = AB THEN SAY 'Equal'
  ELSE SAY 'Not Equal'

  --> Equal

What has happened is that ARexx has converted the "Ab" to "AB" and said
that the two sides of the equation are equal!

This should have been used:-

  IF 'Ab' = 'AB' THEN SAY 'Equal'
  ELSE SAY 'Not Equal'

  --> Not Equal

Another trap in not putting strings into quotes is illustrated by
this:-

  /* Early in program */

  AB = 10
  CD = 10

  /* Later in program */

  IF AB = CD THEN SAY 'Equal'
  ELSE SAY 'Not Equal'

  --> Equal

ARexx knows that "AB" and "CD" are symbols because they are not in quotes
and has therefore @{"compared the values" LINK "symbol"} of the two symbols which are
equal.


@{JCENTER}=== End of Text ===
@{JLEFT}


@ENDNODE

@NODE "Symbol" "Article 11 - Comparison Operators - Symbol Comparisons"

@{B}@{U}@{JCENTER}COMPARISON OF SYMBOL VALUES@{UB}@{UU}
@{JLEFT}
When talking about @{"string comparisons" LINK "String"64} and @{"numeric comparisons" LINK "Numeric"17} we found
out that symbols can be used in comparisons. ARexx will compare the values
of the symbols instead of the symbols themselves.

For example, take this bit of programming:-

  Name1 = 'Jones'
  Name2 = 'Smith'
  IF Name1 = Name2 THEN ...

For the comparison process, ARexx converts the last line to this:-

  IF 'Jones' = 'Smith' THEN ...

and then proceeds along the same lines as @{"string comparisons" LINK "String"}.


@{JCENTER}=== End of Text ===
@{JLEFT}
@ENDNODE

@NODE "Exact" "Article 11 - Comparison Operators - Exact Comparisons"

@{B}@{U}@{JCENTER}EXACT COMPARISONS@{UB}@{UU}
@{JLEFT}
The two EXACT comparisons of equality and inequality (== and ~==) compare
values EXACTLY which means that the comparisons:-

- include any spaces at the start and end of strings.

- include any insignificant zeros in numbers.

  insignificant zeros are those at the start of a number  e.g. 00123
  or those at the end of the decimal part of a number,    e.g. 123.200

Non exact comparisons of equality (= and ~=) ignore these items.

This is best illustrated by the following sets of comparisons using
non-exact and exact comparison on the same strings in each of the sets of
two.

In the following strings there are spaces in various positions. Take
careful note of them when working out why some things that are equal are
not exactly equal.

 ' abc' =  'abc'    --> true leading space of left string ignored
 ' abc' == 'abc'    --> false leading space of left string considered

 ' abc' ~=  'abc'   --> false leading spaces of left string ignored
 ' abc' ~== 'abc'   --> true leading spaces of left string considered

 'abc' =  'abc '    --> true trailing space of right string ignored
 'abc' == 'abc '    --> false trailing space of right string considered

 'abc' ~=  'abc '   --> false trailing spaces of right string ignored
 'abc' ~== 'abc '   --> true trailing spaces of right string considered

 'abc' =  'a b c'   --> false intermediate spaces of right string
                              considered
 'abc' == 'a b c'   --> false intermediate spaces of right string
                              considered

 'abc' ~=  'a b c'  --> true intermediate spaces in right string
                             considered
 'abc' ~== 'a b c'  --> true intermediate spaces of right string
                             considered

Now examine these sets of numbers to see how the insignificant zeros affect
the ordinary and exact comparisons:-

 123 =  123.0     --> true the .0 is insignificant and so ignored
 123 == 123.0     --> false the .0 is taken into the comparison

 123.1 =  123.100 --> true the final 00 is insignificant and so ignored
 123.1 == 123.100 --> false the final 00 is taken into the comparison

 0123 =  123      --> true the leading 0 is insignificant and so ignored
 0123 == 123      --> false the leading 0 is taken into the comparison

@{B}@{U}In Summary@{UB}@{UU}

The differences between non-exact and exact comparisons on strings and
numbers is summarised in this table:-

                              @{U}    NON-EXACT    @{UU}    @{U}      EXACT      
@{UU}
Strings:-

Spaces Leading & Trailing     Ignored              Taken into account
Spaces "in the middle"        Taken into Account   Taken into account

Numbers:-

Insignificant zeros           Ignored              Taken into account

@{B}@{U}When To Use Exact Equality Comparisons@{UB}@{UU}

I think you will find that, in most circumstances, ordinary equality tests
(= and ~=) will be O.K.

If you want to ensure that strings are absolutely identical including
leading and trailing spaces, then use exact equality comparisons (== and
~==).

With numbers, off hand I cannot think of any use for exact equality
comparisons. In fact, the use of exact equality comparisons on numbers may
lead to inaccuracies in your programs. For example:-

  3 / 2 =  1.50   --> true
  3 / 2 == 1.50   --> false

The second line could end up making your program do the wrong thing!!


@{JCENTER}=== End of Text ===
@{JLEFT}
@ENDNODE
