65.9K
CodeProject is changing. Read more.
Home

Fortran Operators .EQ. .GT. .GE. .LT. .LE. .NE. Revisited

starIconstarIconstarIconstarIconemptyStarIcon

4.00/5 (1 vote)

Jun 5, 2011

CPOL
viewsIcon

26182

A C# method which encapsulates the comparison operators.

Here is a C# method that implements the Fortran comparison operators:
public enum CompareType { NC, EQ, GT, GE, LT, LE, NE }; 
// NC:  Not Compared
public static bool VComp(byte[] Lvar, byte[] Rvar, CompareType CT,
                         uint LSBpos, uint MSBpos)
{
  if ((Lvar==null)||(Rvar==null)) return false;
  bool done=false,vc=false,rdy=false;
  uint lim = MinOf((uint)Lvar.Length, (uint)Rvar.Length);
  LSBpos = Range(LSBpos, 0, lim); MSBpos = Range(MSBpos, 0, lim);
  int incr=1; uint loc = LSBpos;
  int count = (int)MaxOf(LSBpos, MSBpos)-(int)MinOf(LSBpos, MSBpos) + 1;
  if (MSBpos>=LSBpos) { incr=-1; loc = MSBpos; }
  CompareType cond = CompareType.NC;
  do
  {
    int z = Lvar[loc]-Rvar[loc];
    if (z>0) cond=CompareType.GT;
    else if (z<0) cond=CompareType.LT;
    count--;
    done = (count <= 0);
    if (done&(cond==CompareType.NC)) cond=CompareType.EQ;
    loc=(uint)((long)loc + incr);
    rdy = (done|(cond!=CompareType.NC));
  } while (!rdy);
  switch (cond)
  {
    case CompareType.GT:
      switch (CT)
      {
        case CompareType.NE: vc=true; break;
        case CompareType.GT: vc=true; break;
        case CompareType.GE: vc=true; break;
      }
      break;
    case CompareType.LT:
      switch (CT)
      {
        case CompareType.NE: vc=true; break;
        case CompareType.LT: vc=true; break;
        case CompareType.LE: vc=true; break;
      }
      break;
    case CompareType.EQ:
      switch (CT)
      {
        case CompareType.EQ: vc=true; break;
        case CompareType.GE: vc=true; break;
        case CompareType.LE: vc=true; break;
      }
      break;
  }
  return vc;
}
public static UInt32 MinOf(UInt32 int1, UInt32 int2)
{ if (int1<int2) return int1; else return int2; }
public static UInt32 MaxOf(UInt32 int1, UInt32 int2)
{ if (int1>=int2) return int1; else return int2; }
public static UInt32 Range(UInt32 inval, UInt32 LoVal, UInt32 HiVal)
{ if (inval<LoVal) inval=HiVal; else if (inval>HiVal) inval=LoVal; return inval; }

// Feed VComp() two buffers, the positions of the most- and
// least- significant bytes in them, and a comparison type,
// and it will return true if the statement <Lvar><Op><Rvar>
// is true given the <Op> comparator.  The method allows the
// start/stop positions to be at unaligned boundaries, and
// doesn't compare 16/32/64 bits at each iteration because
// it may need to be used in comparing random file records or
// fields with odd sizes.
//
// The 'ounce of prevention' code at the start can be
// dispensed with if you are going to hard-code (or
// carefully check) the start/stop offset values in
// the calling code.