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