Team-Fly
Previous Section Next Section

7.4 Comparison Operators

Every program requires the ability to make assertions about the equality or inequality or the size relationship of arithmetic variables, and this holds as well for our dealings with CLINT objects. Here, too, the principle is obeyed that the programmer does not need knowledge of the internal structure of the CLINT type, and the determination of how two CLINT objects are related to each other is left to functions designed for such purposes.

The primary function that accomplishes these tasks is the function cmp_l(). It determines which of the relations a_l < b_l, a_l == b_l, or a_l > b_l holds for two CLINT values a_l and b_l. To this end, first the numbers of digits of the CLINT objects, which have been liberated from any leading zeros, are compared. If the number of digits of the operands is the same, then the process begins with a comparison of the most-significant digits; as soon as a difference is detected, the comparison is terminated.

int
cmp_l (CLINT a_l, CLINT b_l)
{
  clint *msdptra_l, *msdptrb_l;
  int la = DIGITS_L (a_l);
  int lb = DIGITS_L (b_l);
  if (la == 0 && lb == 0)
    {
      return 0;
    }

  while (a_l[la] == 0 && la > 0)
    {
      --la;
    }
  while (b_l[lb] == 0 && lb > 0)
    {
     --lb;
    }

  if (la == 0 && lb == 0)
    {
      return 0;
    }
  if (la > lb)
    {
      return 1;
    }
  if (la < lb)
    {
      return -1;
    }
  msdptra_l = a_l + la;
  msdptrb_l = b_l + lb;

  while ((*msdptra_l == *msdptrb_l) && (msdptra_l > a_l))
    {
      msdptra_l--;
      msdptrb_l--;
    }
 if (msdptra_l == a_l)
   {
     return 0;
   }
 if (*msdptra_l > *msdptrb_l)
   {
     return 1;
   }
 else
   {
     return -1;
   }
}

If we are interested in the equality of two CLINT values, then the application of the function cmp_l() is a bit more than is necessary. In this case there is a simpler variant, which avoids the size comparison.

int
equ_l (CLINT a_l, CLINT b_l)
{
  clint *msdptra_l, *msdptrb_l;
  int la = DIGITS_L (a_l);
  int lb = DIGITS_L (b_l);
  if (la == 0 && lb == 0)
    {
      return 1;
    }
  while (a_l[la] == 0 && la > 0)
    {
      --la;
    }

  while (b_l[lb] == 0 && lb > 0)
    {
      --lb;
    }

  if (la == 0 && lb == 0)
    {
      return 1;
    }

  if (la != lb)
    {
      return 0;
    }

  msdptra_l = a_l + la;
  msdptrb_l = b_l + lb;
  while ((*msdptra_l == *msdptrb_l) && (msdptra_l > a_l))
    {
      msdptra_l--;
      msdptrb_l--;
    }

  return (msdptra_l > a_l ? 0 : 1);
}

These two functions in their raw form can easily lead the user into the thickets of error. In particular, the meaning of the function values of cmp_l() must be kept constantly in mind or looked up repeatedly. As a measure against errors a number of macros have been created by means of which comparisons can be formulated in a more mnemonically satisfactory way (see in this regard Appendix C, "Macros with Parameters"). For example, we have the following macros, where we equate the objects a_l and b_l with the values they represent:

GE_L (a_l, b_l)   returns 1 if a_l  b_l, and 0 otherwise;
EQZ_L (a_l)       returns 1 if a_l == 0, and 0 if a_l > 0.

Team-Fly Previous Section Next Section