12-16-2022, 07:09 PM
Ever want to compare strings, without being called a racist? Well now you can with _STRCMP...
SYNTAX compare% = _STRCMP(string1$, string2$)
What does it do? _STRCMP reads each string from left to right, and compares each ASCII character value. At the first instance where one value is not equal to the other, the function exits and returns:
-1 If the string character being compared in the first string is smaller than the string character being compared in the second string.
0 If the strings are equal.
1 If the string character being compared in the first string is larger than the string character being compared in the second string.
Also, remember that: Upper case letters are valued less than lower case letters in the ASCII evaluation. (Wiki).
So here is a quick function using our Keyword of the Day to see how it "functions."
Well hold on a minute there, Sparky...
What if I input a$ = 99.9 and b$ = 1024?
Well, _STRCMP would correctly return "The first string is larger than the second string." because with left to right evaluation, "9" of a$ is larger than "1" of b$.
To get a method to tell you if the value of a string representing a numeric value like we use in String Math routines, requires a bit of work...
So sure, doing a simple numeric comparison like...
Output 0 for False, which is correct.
...works, but below, using a strings to represent these values, the VAL() function converts our string numbers to S.N. with some loss of accuracy along the way.
Output -1 for True, which is incorrect; as VAL() of both is: 1D+224
So since String Math is designed for enormous numbers, a string comparison function for val() had to be created. If you have an alternative, please post, but otherwise please just keep in mind the difference between _STRCMP, which compares the ASCII character values from left to right, and the function I posted, which compares the numeric value of the strings.
Pete
SYNTAX compare% = _STRCMP(string1$, string2$)
What does it do? _STRCMP reads each string from left to right, and compares each ASCII character value. At the first instance where one value is not equal to the other, the function exits and returns:
-1 If the string character being compared in the first string is smaller than the string character being compared in the second string.
0 If the strings are equal.
1 If the string character being compared in the first string is larger than the string character being compared in the second string.
Also, remember that: Upper case letters are valued less than lower case letters in the ASCII evaluation. (Wiki).
So here is a quick function using our Keyword of the Day to see how it "functions."
Code: (Select All)
DO
LINE INPUT "String 1: "; a$
LINE INPUT "String 2: "; b$: PRINT
IF a$ = "" AND b$ = "" THEN END
PRINT scompare(a$, b$)
PRINT
LOOP
FUNCTION scompare$ (string1$, string2$)
a% = _STRCMP(string1$, string2$)
SELECT CASE a%
CASE -1
scompare$ = "The first string is smaller than the second string."
CASE 0
scompare$ = "The first string is equal to the second string."
CASE 1
scompare$ = "The first string is larger than the second string."
END SELECT
END FUNCTION
Well hold on a minute there, Sparky...
What if I input a$ = 99.9 and b$ = 1024?
Well, _STRCMP would correctly return "The first string is larger than the second string." because with left to right evaluation, "9" of a$ is larger than "1" of b$.
To get a method to tell you if the value of a string representing a numeric value like we use in String Math routines, requires a bit of work...
Code: (Select All)
DO
LINE INPUT "Number 1: "; s1$
LINE INPUT "Number 2: "; s2$
IF s1$ = "" OR s2$ = "" THEN EXIT DO
gl% = 0: sm_greater_lesser s1$, s2$, gl%
SELECT CASE gl%
CASE -1: PRINT s1$; " < "; s2$
CASE 0: PRINT s1$; " = "; s2$
CASE 1: PRINT s1$; " > "; s2$
END SELECT
PRINT
LOOP
SUB sm_greater_lesser (stringmatha$, stringmathb$, gl%)
compa$ = stringmatha$: compb$ = stringmathb$ ' So original variables do not get changed.
DO
WHILE -1 ' Falx loop.
IF gl% = 2 THEN EXIT WHILE ' For bypassing sign and decimal adjustments when only positive non-decimal numbers are being evaluated.
' Remove trailing zeros after a decimal point.
IF INSTR(compa$, ".") THEN
DO UNTIL RIGHT$(compa$, 1) <> "0" AND RIGHT$(compa$, 1) <> "." AND RIGHT$(compa$, 1) <> "-"
compa$ = MID$(compa$, 1, LEN(compa$) - 1)
LOOP
END IF
IF INSTR(compb$, ".") THEN
DO UNTIL RIGHT$(compb$, 1) <> "0" AND RIGHT$(compb$, 1) <> "." AND RIGHT$(compb$, 1) <> "-"
compb$ = MID$(compb$, 1, LEN(compb$) - 1)
LOOP
END IF
IF MID$(compa$, 1, 2) = "-0" OR compa$ = "" OR compa$ = "-" THEN compa$ = "0"
IF MID$(compb$, 1, 2) = "-0" OR compb$ = "" OR compb$ = "-" THEN compb$ = "0"
' A - and +
j% = 0: k% = 0
IF LEFT$(compa$, 1) = "-" THEN j% = -1
IF LEFT$(compb$, 1) = "-" THEN k% = -1
IF k% = 0 AND j% THEN gl% = -1: EXIT DO
IF j% = 0 AND k% THEN gl% = 1: EXIT DO
j&& = INSTR(compa$, ".")
k&& = INSTR(compb$, ".")
' A starting decimal and non-decimal.
IF j&& = 0 AND k&& = 1 THEN
IF compa$ = "0" THEN gl% = -1 ELSE gl% = 1
EXIT DO
END IF
IF k&& = 0 AND j&& = 1 THEN
IF compb$ = "0" THEN gl% = 1 ELSE gl% = -1
EXIT DO
END IF
' remove decimals and align.
j2&& = 0: k2&& = 0
IF j&& <> 0 OR k&& <> 0 THEN
IF j&& THEN compa$ = MID$(compa$, 1, INSTR(compa$, ".") - 1) + MID$(compa$, INSTR(compa$, ".") + 1): j2&& = LEN(compa$) - j&& + 1
IF k&& THEN compb$ = MID$(compb$, 1, INSTR(compb$, ".") - 1) + MID$(compb$, INSTR(compb$, ".") + 1): k2&& = LEN(compb$) - k&& + 1
compa$ = compa$ + STRING$(k2&& - j2&&, "0")
compb$ = compb$ + STRING$(j2&& - k2&&, "0")
END IF
EXIT WHILE
WEND
' Remove leading zeros if any.
DO UNTIL LEFT$(compa$, 1) <> "0"
compa$ = MID$(compa$, 2)
LOOP
IF compa$ = "" THEN compa$ = "0"
DO UNTIL LEFT$(compb$, 1) <> "0"
compb$ = MID$(compb$, 2)
LOOP
IF compb$ = "" THEN compb$ = "0"
' Both positive or both negative whole numbers.
SELECT CASE LEN(compa$)
CASE IS < LEN(compb$)
gl% = -1
CASE IS = LEN(compb$)
IF compa$ = compb$ THEN
gl% = 0
ELSEIF compa$ > compb$ THEN gl% = 1
ELSEIF compa$ < compb$ THEN gl% = -1
END IF
CASE IS > LEN(compb$)
gl% = 1
END SELECT
EXIT DO
LOOP
END SUB
So sure, doing a simple numeric comparison like...
Code: (Select All)
PRINT 99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999997 = 99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999997.1
...works, but below, using a strings to represent these values, the VAL() function converts our string numbers to S.N. with some loss of accuracy along the way.
Code: (Select All)
PRINT VAL("99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999997") > VAL("99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999997.1")
So since String Math is designed for enormous numbers, a string comparison function for val() had to be created. If you have an alternative, please post, but otherwise please just keep in mind the difference between _STRCMP, which compares the ASCII character values from left to right, and the function I posted, which compares the numeric value of the strings.
Pete