home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
kermit.columbia.edu
/
kermit.columbia.edu.tar
/
kermit.columbia.edu
/
scripts
/
ckermit
/
cmp.~2~
< prev
next >
Wrap
Text File
|
2007-12-18
|
3KB
|
55 lines
# Macro CMP - Compare numbers even if they are bigger than machine word size
# \%1 = arithmetic comparison operator (>, <, =, etc, listed below)
# \%2 = first number (signed or unsigned decimal, integer or floating-point)
# \%3 = second number (ditto)
#
# Succeeds if comparison is true, fails if not, or if called incorrectly.
# Example:
# cmp > 987 -0.10001824
# if success { commands if true } else { commands if false }
#
# For comparison the numbers are normalized to 24 decimal places with
# leading zeros before the decimal point, and 24 decimal places with trailing
# zeros after the decimal point. You can change the precision by defining
# \%9 to any other number you with.
#
# F. da Cruz, Columbia U, 18-19 December 2007
#
def cmp {
.\%9 = 24 # Digits before & after decimal point for normalization
.\%8 = 0 # sign of \%2: 0(+) 1(-)
.\%7 = 0 # sign of \%3: 0(+) 1(-)
# Verify arguments
if < \v(argc) 4 end 2 "Usage: CMD operator number number"
if not float \%2 end 2 "CMD: operand not numeric '\%2'"
if not float \%3 end 2 "CMD: operand not numeric '\%3'"
if not \findex(:\%1:,:<:>:<=:>=:!=:=:==:) end 2 "CMD: Bad operator '\%1'"
# Check sign of each number
if eq "\:(\%2[1:1])" "+" .\%2 := \:(\%2[2]) # Strip any leading plus sign
if eq "\:(\%3[1:1])" "+" .\%3 := \:(\%3[2])
if eq "\:(\%2[1:1])" "-" { .\%7 = 1, .\%2 := \:(\%2[2]) } # Note minuses
if eq "\:(\%3[1:1])" "-" { .\%8 = 1, .\%3 := \:(\%3[2]) } # and strip them
if not \fverify(0,\%2) .\%7 = 0 # watch out for "-0"
if not \fverify(0,\%3) .\%8 = 0 # watch out for "-0"
# Handle easy cases first
switch \%7\%8 {
:01, if \findex(:\%1:,:>:>=:!=:) end 0, end 1 # Signs differ
:10, if \findex(:\%1:,:<:<=:!=:) end 0, end 1 # Signs differ
:11, .\%5 := \%2, .\%2 := \%3, .\%3 = \%5 # Both negative - swap args
}
# Get here if we must compare the magnitudes (signs 00 or 11)
# Normalize for lexical comparison \%9 digits before & after decimal point
.\%2 := \flpad(\fword(\%2,1),\%9,0).\frpad(\fword(\%2,2),\%9,0)
.\%3 := \flpad(\fword(\%3,1),\%9,0).\frpad(\fword(\%3,2),\%9,0)
# Make the desired comparison
switch \%1 {
:<, if LLT \%2 \%3 end 0, end 1
:>, if LGT \%2 \%3 end 0, end 1
:\=, if EQU \%2 \%3 end 0, end 1
:\==, if EQU \%2 \%3 end 0, end 1
:!=, if NOT EQU \%2 \%3 end 0, end 1
:<=, if NOT LGT \%2 \%3 end 0, end 1
:>=, if NOT LLT \%2 \%3 end 0, end 1
}
}