home *** CD-ROM | disk | FTP | other *** search
/ kermit.columbia.edu / kermit.columbia.edu.tar / kermit.columbia.edu / scripts / ckermit / cmp.~2~ < prev    next >
Text File  |  2007-12-18  |  3KB  |  55 lines

  1. # Macro CMP - Compare numbers even if they are bigger than machine word size
  2. #  \%1 = arithmetic comparison operator (>, <, =, etc, listed below)
  3. #  \%2 = first number (signed or unsigned decimal, integer or floating-point)
  4. #  \%3 = second number (ditto)
  5. #
  6. # Succeeds if comparison is true, fails if not, or if called incorrectly.
  7. # Example:
  8. #  cmp > 987 -0.10001824
  9. #  if success { commands if true } else { commands if false }
  10. #
  11. # For comparison the numbers are normalized to 24 decimal places with
  12. # leading zeros before the decimal point, and 24 decimal places with trailing
  13. # zeros after the decimal point.  You can change the precision by defining
  14. # \%9 to any other number you with.
  15. #
  16. # F. da Cruz, Columbia U, 18-19 December 2007
  17. #
  18. def cmp {
  19.     .\%9 = 24  # Digits before & after decimal point for normalization
  20.     .\%8 = 0   # sign of \%2: 0(+) 1(-)
  21.     .\%7 = 0   # sign of \%3: 0(+) 1(-)
  22.     # Verify arguments
  23.     if < \v(argc) 4 end 2 "Usage: CMD operator number number"
  24.     if not float \%2 end 2 "CMD: operand not numeric '\%2'"
  25.     if not float \%3 end 2 "CMD: operand not numeric '\%3'"
  26.     if not \findex(:\%1:,:<:>:<=:>=:!=:=:==:) end 2 "CMD: Bad operator '\%1'"
  27.     # Check sign of each number
  28.     if eq "\:(\%2[1:1])" "+" .\%2 := \:(\%2[2]) # Strip any leading plus sign
  29.     if eq "\:(\%3[1:1])" "+" .\%3 := \:(\%3[2])
  30.     if eq "\:(\%2[1:1])" "-" { .\%7 = 1, .\%2 := \:(\%2[2]) } # Note minuses
  31.     if eq "\:(\%3[1:1])" "-" { .\%8 = 1, .\%3 := \:(\%3[2]) } # and strip them
  32.     if not \fverify(0,\%2) .\%7 = 0 # watch out for "-0"
  33.     if not \fverify(0,\%3) .\%8 = 0 # watch out for "-0"
  34.     # Handle easy cases first
  35.     switch \%7\%8 {
  36.       :01, if \findex(:\%1:,:>:>=:!=:) end 0, end 1 # Signs differ
  37.       :10, if \findex(:\%1:,:<:<=:!=:) end 0, end 1 # Signs differ
  38.       :11, .\%5 := \%2, .\%2 := \%3, .\%3 = \%5 # Both negative - swap args
  39.     }
  40.     # Get here if we must compare the magnitudes (signs 00 or 11)
  41.     # Normalize for lexical comparison \%9 digits before & after decimal point
  42.     .\%2 := \flpad(\fword(\%2,1),\%9,0).\frpad(\fword(\%2,2),\%9,0)
  43.     .\%3 := \flpad(\fword(\%3,1),\%9,0).\frpad(\fword(\%3,2),\%9,0)
  44.     # Make the desired comparison
  45.     switch \%1 {
  46.       :<,  if LLT \%2 \%3 end 0, end 1
  47.       :>,  if LGT \%2 \%3 end 0, end 1
  48.       :\=,  if EQU \%2 \%3 end 0, end 1
  49.       :\==, if EQU \%2 \%3 end 0, end 1
  50.       :!=, if NOT EQU \%2 \%3 end 0, end 1
  51.       :<=, if NOT LGT \%2 \%3 end 0, end 1
  52.       :>=, if NOT LLT \%2 \%3 end 0, end 1
  53.     }
  54. }
  55.