COMP%
=====
Compare two values of any type
This is an expansion of my original CMP% function which was limited to
strings only.
Usage:
======
result% = COMP%(X, Y, <cmptype.b><vartype.b))
Where
result% is either 1 => X > Y or
0 => X = Y or
-1 => X < Y
X and Y are the two values to be compared. They are assumed to be
of the same type.
<cmptype.b> in the most significant byte of the word is the code
for the Qdos comparision type 0..3 (see below for details)
The <cmptype> is only significant for string comparisions
and is otherwise ignored.
If ct% = 1 (case agostic string comparison) and vt% = 14
(variable type string) then ct% * 256 + vt% will meet the
case:
r% = COMP%('abc', 'ABC', 256 + 14) returns r% = 0
r% = COMP%('abc', 'ABC', 14) returns r% = -1
<vartype.b> in the least significant byte of the parameter is a
code defining the kind of parameters to be compared (see
below).
Variable types:
===============
sbyte = $00 = 0 signed byte
ubyte = $02 = 2 unsigned byte
sword = $04 = 4 signed 16 bit word
uword = $06 = 6 unsigned 16 bit word
slong = $08 = 8 signed 32 bit long word
ulong = $0A = 10 unsigned 32 bit long word
fltpt = $0C = 12 48 bit float
qstrg = $0E = 14 Q-string (len.w + bytes)
cstrg = $10 = 16 C-string (zero-terminated)
nstrg = $12 = 18 Name string (1 byte length)
S*BASIC doesnt normally deal with unsigned integers word or
longword, so the unsigned word 64302 has to be entered as -31534
(= 32768 - 64302). Bytes in S*BASIC are always treated as unsiged. COMP%
lets you treat them as signed or unsigned.
Types 0 to 6 are fetched by S*BASIC as standard word integers, types 8 and
10 as long word integers, type 12 as standard floating point numbers, and
type 14 as standard strings. Types 16 and 18 are not supported by COMP%,
they must be converted to Q-strings first. You could use CSTR$ and NSTR$,
as found at Knoware.no for that, if the strings are stored in memory
String comparison:
==================
Comparisons may be:
Type 0 Made directly on a character by character basis
Type 1 Made ignoring the case of the letters
Type 2 Made using the value of any embedded numbers
Type 3 Both ignoring the case of letters and using the value of embedded
numbers.
More detail of the order of characters etc, may be found in the various QL
Concepts manuals, or in the text accompanying my CMP% keyword at Knoware.no
Examples:
=========
COMP% doesnt do coersion, ie make one type of variable into the same class
as another before comparing them; both variables are assumed to be of the
same type. However, S*BASIC's parameter fetching routines do coercion
pretty well, so you can make use of this:
FOR t = 0 to 14 STEP 2: PRINT COMP%(190, 22, t),
This will print -1 followed by six 1s and a final -1. How come?
t = 0 = sbyte. Signed byte 190 is the negative number -66, so -66 < 120
t = 14 = qstrg. With normal strings the 1 in 192 is < than the 2 in 22
S*BASIC converts, or tries to, the parameters to integers, longs, floats or
strings before the comparison takes place using the type specified.
With qstrgs we have one more card to play. If the comparison type includes
the value of embedded numbers the caclulation changes:
PRINT COMP%(190, 22, 2 * 256 + 14) - prints 1, because 190 > 22. The same
for PRINT COMP%(190, 22, 3 * 256 + 14), representing string comparison
type 2 and 3, as mentioned above.
The following listing is an example of COMP% used to sort arrays of various
kinds. RUN in in the standard S*BASIC 3-window console. Press a key after
the BEEP and check out the differences.
10 RANDOMISE
12 DIM A%(9), A(9), A$(9, 10)
14 FOR i = 0 TO DIMN(A%)
16 A%(i) = RND(0 TO 255)
18 A(i) = RND(-512 TO 512)
20 IF RND(1) THEN
22 A$(i) = CHR$(RND(65 TO 90))
24 ELSE
26 A$(i) = CHR$(RND(97 TO 122))
28 END IF
30 END FOR i
32 :
34 Dis#2
36 BIS A%, 0: rem Unsigned byte
38 BIS A , 4: rem Unsigned word
40 BIS A$, 14: rem String; comp type 0
42 Dis#1
44 BEEP 2000, 2: PAUSE
46 :
48 BIS A%, 2: rem Signed byte
50 BIS A , 6: rem Signed word
52 BIS A$, 14 + 256: rem String; comp type 1 (ignore case)
54 Dis#2
56 :
58 DEFine PROCedure Dis(ch)
60 LOCal i
62 CLS#ch
64 FOR i = 0 TO DIMN(A%)
66 PRINT#ch; A%(i), A(i), A$(i)
68 END FOR i
70 END DEFine Dis
72 :
74 :
100 rem + ------------------------------------------------------------------------ +
102 rem |< BIS >|
104 rem + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +
106 rem | Straight (Binary) Insertion Sort |
108 rem | |
110 rem | TAOCP 5.2.1 |
112 rem | |
114 rem | Stable! Sorts arrays of any type. |
116 rem | |
118 rem | Dependency: COMP% |
120 rem + ------------------------------------------------------------------------ +
122 rem | V0.01, pjw, 1993 Apr 23, adapted for SuperBASIC from algorithm |
124 rem | V0.01, pjw, 2023 Aug 19, uses COMP% types |
126 rem + ------------------------------------------------------------------------ +
128 :
130 DEFine PROCedure BIS(arr, type%)
132 LOCal sl, j%, i%, t$
134 FOR j% = 1 TO DIMN(arr)
136 t$ = arr(j%): i% = j% - 1
138 REPeat sl
140 IF COMP%(t$, arr(i%), type%) >= 0: EXIT sl
142 arr(i% + 1) = arr(i%)
144 i% = i% - 1: IF i% <= -1: EXIT sl
146 END REPeat sl
148 arr(i% + 1) = t$
150 END FOR j%
152 END DEFine BIS
154 :
156 :
Status of This software:
========================
V0.01, pjw, 2023 Jul 28, first release
Conditions and DISCLAIMER as per Knoware.no
Generated by QuickHTM, 2023 Aug 19