GO BACK Copyright (c) Kyla Computing 2002-2007 - FOR REXX TRAINING CALL 01273 841160

FUNCTION INDEX

ABBREV
ABS
B2C
BITAND
BITOR
BITXOR
C2B
C2X
CENTER
CENTRE
COMPARE
CONDITION

COPIES
D2C
DATATYPE
DATE
DELSTR
DELWORD
DIGITS
ERRORTEXT
FORM
FORMAT
FUZZ

INDEX
INSERT
LASTPOS
LEFT
LENGTH
MAX
MIN
OVERLAY
POS
RANDOM
REVERSE

RIGHT
SOURCELINE
SPACE
STRIP
SUBSTR
SUBWORD
SYMBOL
TIME
TRANSLATE
TRUNC
VALUE

VERIFY
WORD
WORDINDEX
WORDLENGTH
WORDPOS
WORDS
X2C
X2D
XRANGE

SECTION INDEX

THE LANGUAGE

STRING FUNCTIONS

OTHER FUNCTIONS

PARSE EDITOR

CONCEPTS
INSTRUCTIONS
CONDITIONS
LOOPS
OTHERS

ALIGNMENT
COMPARISON
COMBINING
EXTRACTION
SEARCH
OTHER

WORD
NUMBER
CONVERSION
BIT
PROGRAM

PARSE


TOP . . NEXT . . SECTION INDEX . .FUNCTION-LIST . .HOME

2. String Functions

2.1 String Alignment Functions: CENTER, CENTRE, LEFT & RIGHT

   CenteredString      = CENTER( Instr, Length, PadChar)
   CenteredString      = CENTRE( Instr, Length, PadChar)
   LeftAdjustedString  = LEFT(   Instr, Length, PadChar)
   RightAdjustedString = RIGHT(  Instr, Length, PadChar)

All of these are pretty standard really. LEFT & RIGHT are normally used to ensure that a string is a particular length for printing alignment. The LEFT function can be used to see if the first characters of one string are the same as another but it is better to use the ABBREV function for that type of thing.

 CENTRE('hello',14)   = '    hello     '
 CENTER('=1234567890  =',5) = '34567'  CENTER('abc',8,'-')      = '--abc---'
 LEFT('123456789',12) = '123456789   ' RIGHT('1223456789',12,'-')= '---123456789'
 LEFT('123456789',4)  = '1234'         RIGHT('123456789',4)     = '6789'

Note that you can use either the word CENTRE or CENTER it doesn't matter. It hardly needs saying but in all of these functions (and loads of others) the default pad character is a space. This pad is used when the source string is shorter than the length. If the CENTRE can not get it exactly right because there is an odd number of spaces, the leading gap is smaller.


TOP . . NEXT . . PREVIOUS . . SECTION INDEX . . FUNCTION-LIST . . HOME

2.2 String Comparison Functions: COMPARE & ABBREV

  DiffCharNo  = COMPARE(String1,    String2 ,   PadChar)
  Boolean     = ABBREV( LongString, ShortString , MinLength)

These two are doing exactly what they say they are: COMPARE compares two strings while ABBREV checks that one string is an abbreviation of the other. Note the odd purpose of the last argument on ABBREV, it checks that the abbreviated string is of a particular length! If it's not the function will always return a 0.

  COMPARE('ABC','ABC')       = 0; ABBREV('abcdefghi','abcd')  = 1
  COMPARE('ABCD','ABC')      = 4; ABBREV('abcdefghi','abzz')  = 0
  COMPARE('ABC','ABCD')      = 4; ABBREV('abcdefghi','abcd',6)= 0
  COMPARE('ABCD','ABcD')     = 3; ABBREV('abcdefghi','abcd',4)= 1
  COMPARE('WXYZ    ','WXYZ') = 0;
  COMPARE('ABC---','ABC-','-')=0

Note that COMPARE is returning the position of the first mis-match while ABBREV is returning a Boolean 0 or a 1. On the second to last example ABBREV has returned a '0' because the second string is not 6 characters in length!


TOP . . NEXT . . PREVIOUS . . SECTION INDEX . . FUNCTION-LIST . . HOME

2.3 String Combining Functions: OVERLAY & INSERT

   BothString= INSERT( StringtobeInserted, BaseString, at, Length, Pad)
   String    = OVERLAY( OverlayingString,  BaseString, at, Length, Pad)

These two are used to put all or part of one string into another. The difference between the two functions is obvious INSERT doesn't over type any of the second string. Again we have a pad character (the default is a space) if the our string is less than the length we want to insert or overlay.

   INSERT('12345','abcdef')          = '12345abcdef'
   INSERT('12345','abcdef',3)        = 'abc12345def'
   INSERT('12345','abcdef',3,2)      = 'abc12def'
   INSERT('123','abcdef',2,5,'*')    = 'ab123**cdef'
   OVERLAY('12345','abcdefghi')      = '12345fghi'
   OVERLAY('12345','abcdefghi',3)    = 'ab12345hi'
   OVERLAY('12345','abcdefghi',3,2)  = 'ab12efghi'
   OVERLAY('123','abcdefghi',2,5,'*')= 'a123**ghi'

The most confusing thing here is the order of the first two strings, from these examples you can see that it's the 2nd argument, which is overlaid/inserted into the 1st argument.
I use OVERLAY a lot when creating output lines. I set a line to be blank and then use OVERLAY to put into the output the variables at the required column. This may not be very efficient, but if that doesn't matter too much, you will find it very easy to built up an output line and modify it later. For example:

    OUT = ""
    OUT = OVERLAY( TimeVar , OUT , TIMECOLUMN )
    OUT = OVERLAY( DateVar , OUT , DATECOLUMN )
    OUT = OVERLAY( NameVar , OUT , NAMECOLUMN )
    SAY OUT


TOP . . NEXT . . PREVIOUS . . SECTION INDEX . . FUNCTION-LIST . . HOME

2.4 String Extraction Functions: SUBSTR & DELSTR

   Sub-string  = SUBSTR( String, StartofBitRequired, Length)
   Sub-string  = DELSTR( String, StartBittoBeLeftOut,Length)

These functions are all to do with extracting part of string and putting it into another. DELSTR will delete a section of a string while SUBSTR does the opposite and extracts a section. You will find you hardly ever use DELSTR and use SUBSTR all the time With DELSTR if you don't code a length it will delete from the start point to the end of the string. With SUBSTR not coding a length means you get everything from the start position and the end of the string. When we say 'delete a section of the string' we don't mean that 'InStr' is change.

   DELSTR('12345678',5)= '1234'           DELSTR('12345678',4,2)   = '123678'
   DELSTR('abcdefgh',12)    = 'abcdefgh'  SUBSTR('12345678',4)     = '45678'
   SUBSTR('12345678',4,2)   = '45'        SUBSTR('12345678',14,2)  = '  '
   SUBSTR('12345678',5,7)   = '5678   '   SUBSTR('12345678',5,7,'-')=  '5678---'

As usual here are some amazing examples. Look at the first one, note that '5' is not in the returned string because it is the first character of the block to be deleted. Compare this with the first SUBSTR example where we do get a '4' because this is the first character of the sub-section that we require. Note if you find you need more than one SUBSTR instruction when getting different bits out of the same string, you should consider using PARSE VAR instead!!


TOP . . NEXT . . PREVIOUS . . INDEX . . SECTION INDEX . . FUNCTION-LIST . . HOME

2.5 String Search Functions: INDEX, POS & LASTPOS

   PosNum  = POS(     StringtobeFound, StringToLookIn, Start)
   PosNum  = INDEX(   StringToLookIn , StringtobeFound,Start)
   PosNum  = LASTPOS( StringtobeFound, StringToLookIn, Start)

These all search one string (the 'StingToLookIn' string) to see if it contains another (the 'StringToBeFound' string). POS and INDEX are the same but the 1st and 2nd arguments are coded in the reverse order. With any of these functions coding a 3rd argument limits the area searched. They return the start position within the 'target' string, which matches the 'find' string. LASTPOS searches from the right hand end of the 'target' string but it still returns the position from the front of the string.

  POS('x', '1234567x90ABCDxFG')    = 8  POS('xx','1234567xx0ABCDxxG',10)= 15
  POS('z', '1234567x90ABCDxFG')   =  0  INDEX('1234567xx0ABCDxxG','xx') =  8
  LASTPOS('x','1234567x90ABCDxFG')= 15  LASTPOS('x','123x567x90ABCDxFG',10)=  8

Here are some examples to have a look at. Note that the functions return a '0' if the string is not found. Some platforms do not support both POS and INDEX (my Amiga does of course) but obviously this is not a headache. If you are looking for a single word (i.e. some letters with spaces either side) then you many want to use the WORDPOS function although this returns the word number not its position.


TOP . .NEXT . .PREVIOUS . .SECTION INDEX . .FUNCTION-LIST . .HOME

2.6 Other String Functions

2.6.1 The COPIES & RANDOM Functions

  LongOutString  = COPIES( StringTobeRepeated, NumberRequired)
  RandomNumber   = RANDOM( LowestNumber, HighestNumber )

COPIES is used to multiple a string a number of times. It is far more useful than it sounds. If you wish to output lines of dashes or asterisks then use this function to generate them with a PageWidth variable in the second argument. That way when (not if) you decide you want longer or shorter lines you change one constant at the top.
There is nothing odds about them worth mentioning, may be just that while on the Amiga only the first character of StringTobeRepeated is used on TSO its the whole string! Below is a near little program COPIES and RANDOM can be used.

  /* REXX showing COPIES and RANDOM functions */
  Array. = 0 ;    PageWidth = 44
DO UNTIL Array.RandNum = (PageWidth - 8)  /* DO TIL WEVE HAD ONE NO. 36 times */
    RandNum = RANDOM(1,10)                 /* GET RANDOM NUMBER BETWEEN 1 -10  */
Array.RandNum = Array.RandNum + 1 ; END  /* COUNT NO.OF TIMES WE GOT THIS NO.*/
  SAY  COPIES("*", PageWidth)              /* PRINT LINE OF STARS */
  DO X = 1 TO 10                           /* PRINT NO.OF TIMES WE GOT RANDOM..*/
    SAY RIGHT(X,2) RIGHT(Array.X,2) COPIES("*", Array.X )
    END                                    /* ...NO. + LINE FOR BAR GRAPH */
  SAY  COPIES("*", PageWidth)              /* PRINT LINE OF STARS */
-----------------------------------------------------------------------
  ********************************************
  1   23 ***********************
  2   20 ********************
  3   14 **************
  4   17 *****************
  5    9 *********
  6   36 ************************************
  7   26 **************************
  8   22 **********************
  9   22 **********************
  10  25 *************************
  ********************************************


TOP . . NEXT . . PREVIOUS . . SECTION INDEX . . FUNCTION-LIST . . HOME

2.6.2 The LENGTH Function

   LengthofString  = LENGTH( String )

If you need help working out what this one can do its pretty sad. However one of the examples may give you a surprise, look at the last one!!!!

   LENGTH(123456789)      = 9    LENGTH(")              = 0
   LENGTH(ABCDEFGHIJKLM)  = 13   LENGTH(COPIES("*",50)) = 50
   LENGTH("12.000000000") = 12


TOP . . NEXT . . PREVIOUS . . SECTION INDEX . . FUNCTION-LIST . . HOME

2.6.3 The REVERSE string function

    ReversedString = REVERSE( StringToBeReveresed )

This is a very silly function, I am sure there is an anorak who thinks that one day they may want to reverse the contents of a string but who else!

  REVERSE('abcdefghijk') = 'kjihgfedcba'


TOP . . NEXT . . PREVIOUS . . SECTION INDEX . . FUNCTION-LIST . . HOME

2.6.4 The STRIP function

 StrippedString = STRIP( StringToBeStripped , Options, Char )

This is very useful, it is usually used to ensure you have no spaces at the being or end of a string, however it can be used just to clear leading or trailing spaces or in fact any other characters.

 STRIP('  remove spaces  ')     = 'remove spaces'
 STRIP('  leading only   ','l') = 'leading only   '
 STRIP('  trailing only  ','t') = '  trailing only'
 STRIP('  both (default) ','b') = 'both (default)'
 STRIP('---remove dashes---','b','-') = 'remove dashes'


TOP . . NEXT . . PREVIOUS . . SECTION INDEX . . FUNCTION-LIST . . HOME

2.6.5 The TRANSLATE function

   OutStr = TRANSLATE(Instr,  TranO, TranI, Pad )

There are two purposes for this function, one simple, one not. If you just code one argument then all lower case characters in 'InStr' are converted to capitals! That's the simple one use. If 3 or 4 arguments are given then the conversion (translation) is more complex. The functions takes the 1st character in 'TranI' and hunts through 'InStr' and tries to finds all occurrences of this, these are changed into the first character in the 'TranO' string. In then hunts for the any occurrence of the 2nd character in 'TranI' and converts this to the second character in 'TranO' . It keeps going until all characters in 'TranI' have been converted. If it runs out of characters in 'TranO' then all remaining character in 'TranI' are converted to the pad character.

   TRANSLATE('abcdefghi')             = 'ABCDEFGHI'
   TRANSLATE('abcdef','123','abc')    = '123def'
   TRANSLATE('abcdef','1','abcd','*') = '1***ef'
   TRANSLATE('No Exclaiming! Or questions?','','!?','.')
          = ' No Exclaiming. Or Questions.'

This starts off being quite sensible and ends up being heavily hairy. The first example shows a straightforward conversion to upper case characters. Look at the second example. This is converting any 'a' characters to '1's, any 'b's to '2's and any 'c's o '3's. All other characters are left alone - they are not even changed into upper case. The third example shows what happens when you add a 4th argument and the 2nd is shorter than the 3rd. Now any 'a's are converted into '1's but there are no character to correspond with b, c or d. Now that take the value of the 4th argument! A semi-practical example is shown last. Here we are converting all '!' and '?' to '.'.


TOP . . NEXT . . PREVIOUS . . SECTION INDEX . . FUNCTION-LIST . . HOME

2.6.6 The VERIFY function

   Number = VERIFY(Instr, RefStr  , Opt, Start  )

VERIFY can be used to check that all the characters in a 'target' string are in another 'reference' string. If there are no rogue character it returns a 0, if there are it's the position of the first bad one.

   VERIFY('4567','1234567890') = '0'
   VERIFY('45x7','1234567890') = '3'

Here are some examples. The first checks to see if the string '4567' just contains any character between 0 and 9, as it does the result is a zero. In the second example the 'x' means the result is 3, the position of the 'x' .


TOP . . NEXT . . PREVIOUS . . SECTION INDEX . . FUNCTION-LIST . . HOME

2.6.7 The XRANGE function

XRANGE is an odd beast it will return a string which contains all the characters within an ASCII range - It can be use to build the reference strings needed for VERIFY. If you don't understand all this don't loose any sleep over it. We can use XRANGE with VERIFY like this:

   VERIFY('456e76',XRANGE('0','9'))    = '4'
   VERIFY('somechar',XRANGE('a','z'))  = '0'
   VERIFY('some char',XRANGE('a','z')) = '5'

Three of the examples show how we can build the reference string required for VERIFY with XRANGE. This could be much easier if it's a very long range.




TOP . . NEXT . . PREVIOUS . . SECTION INDEX . . FUNCTION-LIST . . HOME

3. 3. Other Functions

3.1.1 The WORD function

   TheNthWord = WORD(InputString, NoOfWordRequired )

Highly simple this, the WORD function always returns one word of an input string, which word will depend on the number given in the second argument.

   WORD('one two three four five',3) =  'three'
   WORD('one two three four five',1) =  'one'
   WORD('one two three four five',6) =  ''

Not a lot more to say really except remember there is also a WORDS function (returns the number of words in a string) and its easy to get the two confused.


TOP . . NEXT . . PREVIOUS . . SECTION INDEX . . FUNCTION-LIST . . HOME

3.1.2 The WORDINDEX function

   PositionofWordNumber = WORDINDEX( InputString, WordNumber )

This function returns the position of a word!!! You can see from the examples below the position is the character position.

   WORDINDEX('one two three four five',3) = '9'
   WORDINDEX('one two three four five',4) = '15'

Don't get this function confused with WORDPOS , which is searching a string for a word.


TOP . . NEXT . . PREVIOUS . . SECTION INDEX . . FUNCTION-LIST . . HOME

3.1.3 The WORDPOS function

   WordNumber = WORDPOS( FindThisWord, InThisString, StartWordNo  )

This function searches a string for a word and returns the word number if the word is found.

   WORDPOS('four','one two three four five'  ) = '4'
   WORDPOS('five','one two three four five',3) = '5'

Don't get this function confused with WORDINDEX function.


TOP . . NEXT . . PREVIOUS . . SECTION INDEX . . FUNCTION-LIST . . HOME

3.1.4 The WORDLENGTH function

   LengthOfWord  = WORDLENGTH( StringToLookIn , WordNo )

This function returns the length of a word within a string, the second argument gives the number of the word for which we require the length.

   WORDLENGTH('one two three four five',3) =  '5'
   WORDLENGTH('one two three four five',5) =  '4'

Don't get this function confused with WORDINDEX function.


TOP . . NEXT . . PREVIOUS . . SECTION INDEX . . FUNCTION-LIST . . HOME

3.1.5 The SUBWORD function

   PartOfInString = SUBWORD( InString, FirstWordNo,  NoOfWords )

This function extracts part of string, the second argument gives the first word to be copied and the third argument gives the no of words to be copied.

   SUBWORD('one two three four five',3) = 'three four five'
   SUBWORD('one two three four five',3,2) = 'three four'

You may be better off using SUBSTR which works on character positions and character length it all depends on what you are doing.


TOP . . NEXT . . PREVIOUS . . SECTION INDEX . . FUNCTION-LIST . . HOME

3.1.6 The DELWORD function

   MostOfString = SUBWORD(String, FirstWordNotCopied ,  NoOfWordsNotCopied )

This function copies the whole string except a block defined by the 2nd and 3rd arguments. The 2nd argument is the number of the first word not to be copied and the 3rd argument (if coded) is the number of words not to be copied. If the 3rd argument is not coded all the remaining words are not copied.

   DELWORD('one two three four five',3) = 'one two '
   DELWORD('one two three four five',3,2) =  'one two five'


TOP . . NEXT . . PREVIOUS . . SECTION INDEX . . FUNCTION-LIST . . HOME

3.1.7 The WORDS function

   NoOfWords = WORDS( String )

This very simply tells you have many words are in a string!

   WORDS('one two three four five') = '5'
   WORDS('' ) =  '0'

Don't get this function confused with WORDS!


TOP . . NEXT . . PREVIOUS . . SECTION INDEX . . FUNCTION-LIST . . HOME

3.1.8 The SPACE function

   SpacedString = SPACE(String, NoOfSpaces ,  PadChar )

In its simplest form this function will output a string with only one space between each word. However to get this to happen you must give the 2nd argument a value of 1. Its default value is zero, which will remove all the spaces. If a 3rd argument is coded, this is the character between the words (the default being a space of course)

   SPACE('  one   two three  four  ') = 'onetwothreefour'
   SPACE('  one   two three  four  ',1) = 'one two three four'
   SPACE('  one   two three  four  ',3,'_') =  'one___two___three___four'


TOP . . NEXT . . PREVIOUS . . SECTION INDEX . . FUNCTION-LIST . . HOME

3.2 Number Functions(and instructions)

3.2.1 The TIME function

   CurrentTime  = TIME( Option )
Options:
       'N' = hh:mm:ss (default)    'H' = hh (whole since midnight)
       'L' = hh:mm:ss.uuuuuu       'M' = mm (whole since midnight)
       'R' = Reset Timer           'S' = ss (whole since midnight)
       'E' = Elasped time since reset  'C' = hh:mmAM/PM

The little baby has two uses, the first obvious one is to tell you what the time is on any of the formatted detailed above. It can also be used as a timer which can be very useful as well as a bit of fun. Code TIME('R') near the beginning of a block of code and SAY "elapsed time=" TIME('E') after it. Record the time and then try changing the code, use different functions of many be different loop options. Record the time again and see if you change has altered the speed of your code. Sometimes the results are quite surprising.

       TIME()     = '20:04:41'
       TIME('N')  = '20:04:41'
       TIME('C')  = '8:04PM'
       TIME('H')  = '20'      -completed hours from midnight.
       TIME('M')  = '1204'    -completed mins. from midnight.
       TIME('S')  = '72281'   -completed secs. from midnight.
       TIME('R')  = '0.00'    - Start timer.
       DO X = 1 TO 1000: END
       TIME('E')  = '0.006'    -seconds since reset.

If you want the split up the current time considering using PARSE with an instruction like this:

     PARSE VALUE TIME() WITH hhVar ':' mmVar ':' ssVar


TOP . . NEXT . . PREVIOUS . . SECTION INDEX . . FUNCTION-LIST . . HOME

3.2.2 The DATE function

   TodaysDate  = DATE( Option )
Options:
       'N' = dd mon yyyy (default)    'E' = dd/mm/yy
       'B' = days from 01/01/0000     'U' = mm/dd/yy
       'D' = Julian Date              'O'=  yy/mm/dd
       'J' = Julian Date              'S' = yyyymmdd
       'W' = Weekday                  'M' = Month

Here WYSIWYG. Note that I have found the 'J' option doesn't work on all platforms.

       DATE()       =  '02 Nov 1997'
       DATE('N') (Normal)   =  '02 Nov 1997'
       DATE('E')(European)  =  '02/11/97'
       DATE('U') (USA)      =  '11/02/97'
       DATE('O') (Ordered)  =  '97/11/02'
       DATE('S') (Sorted)   =  '97/11/02'
       DATE('D') (Julian)   =  '306'
       DATE('M') (Month)    =  'November'
       DATE('W') (Weekday)  =  'Sunday'
       DATE('B') (Base)     =  '729695'

Don't try and work out the 'B' unless you understand all the rules for leap year and you now your date-alignment history!!


TOP . . NEXT . . PREVIOUS . . SECTION INDEX . . FUNCTION-LIST . . HOME

3.2.3 NUMERIC instruction, DIGITS & FUZZ functions

Numeric Precision
The program below shows how you can vary the precision of numbers and also the precision of numerical comparisons. The instruction N UMERIC DIGITS will set the precision as you can see here. The maximum is platform specific. D IGITS() will return the current setting.
The F UZZ keyword gives the reduction of precision when performing numerical comparisons. F UZZ() will return the current setting. The default is zero.

   /* REXX To show DIGITS & FUZZ Functions    */
   SAY "Current Precision =" DIGITS() "so 22 / 7 =" 22 / 7
   NUMERIC DIGITS 6
   SAY "After 'NUMERIC DIGITS 6'"
   SAY "Now Precision = " DIGITS() "now 22 / 7 =" 22 / 7
   A = 1.11144 ; B = 1.11122
   SAY "DIGITS FUZZ Prec-  __A__   __B__ "
   SAY " ( )   ( )  ision /     \ /     \"
   DO MyFuzz  = 0 TO DIGITS() - 1
     NUMERIC FUZZ MyFuzz
     Prec = DIGITS() - MyFuzz
     UScore = LEFT(COPIES(" ",Prec+1) || COPIES("_",FUZZ()) ,7)
     SAY COPIES(" ",17) UScore UScore
     Text = " " DIGITS() "   " FUZZ() "   " DIGITS() - FUZZ() " " A  B
     IF A = B THEN SAY Text "- considered the same."
             ELSE SAY Text "- considered different.";   END
   -----------------------------------------------
   Current Precision = 9 so 22 / 7 = 3.14285714
   After 'NUMERIC DIGITS 6'
   Now Precision =  6 now 22 / 7 = 3.14286
   DIGITS FUZZ Prec-  __A__   __B__
    ( )   ( )  ision /     \ /     \
     6     0     6   1.11144 1.11122 - considered different.
                     _       _
     6     1     5   1.11144 1.11122 - considered different.
                     __      __
     6     2     4   1.11144 1.11122 - considered different.
                     ___     ___
     6     3     3   1.11144 1.11122 - considered the same.
                     ____    ____
     6     4     2   1.11144 1.11122 - considered the same.
                     _____   _____
     6     5     1   1.11144 1.11122 - considered the same.


TOP . . NEXT . . PREVIOUS . . SECTION INDEX . . FUNCTION-LIST . . HOME

3.2.4 Exponential Notation functions

REXX supports two formats of exponential notation. The default is SCIENTIFIC which has one digit ( 'power of ten' value) before the decimal point, or you can choose ENGINEERING where the number before the decimal point is always a multiple of 3. Numbers are displayed in exponential format when they get too larger or too small. Note the 'E' can be in any case.

   /* REXX To show the FORM Function            */
   NUMERIC DIGITS 5
   SAY 'After "NUMERIC DIGITS 5" then DIGITS() ='  DIGITS()
   DO A = 3 TO 6
     SAY "1.234  * 10 **" A "=" 1.234 * 10 ** A ; END
   NUMERIC FORM SCIENTIFIC
   SAY 'After "NUMERIC FORM SCIENTIFIC" then FORM() ='  FORM()
   DO 2 ;
     DO A = 3 TO 6
       SAY "1.234  * 10 **" A "=" 1.234 * 10 ** A ;  END
     IF FORM() = 'SCIENTIFIC' THEN DO
       NUMERIC FORM ENGINEERING
       SAY 'After "NUMERIC FORM ENGINEERING" then FORM() =' FORM()
       END; END
   -----------------------------------------------
   After "NUMERIC DIGITS 5" then DIGITS() = 5
   1.234  * 10 ** 3 = 1234.0
   1.234  * 10 ** 4 = 12340
   1.234  * 10 ** 5 = 1.234E+5
   1.234  * 10 ** 6 = 1.234E+6
   After "NUMERIC FORM SCIENTIFIC" then FORM() = SCIENTIFIC
   1.234  * 10 ** 3 = 1234.0
   1.234  * 10 ** 4 = 12340
   1.234  * 10 ** 5 = 1.234E+5
   1.234  * 10 ** 6 = 1.234E+6
   After "NUMERIC FORM ENGINEERING" then FORM() = ENGINEERING
   1.234  * 10 ** 3 = 1234.0
   1.234  * 10 ** 4 = 12340
   1.234  * 10 ** 5 = 123.4E+3
   1.234  * 10 ** 6 = 1.234E+6

In the program above you can see how the exponential format can be changed. Note how the NUMERIC DIGITS instruction can be used to alter the length a number needs to be before the exponential format is invoked. The usual default is 9 but the D IGITS() function will always tell you what the value is.


TOP . . NEXT . . PREVIOUS . . SECTION INDEX . . FUNCTION-LIST . . HOME

3.2.5 The FORMAT Function

The format function can be used to ensure a number is in a specific format.

   FormatedNumber = FORMAT( Number, Digits, DecimalDigits )

The 2nd argument gives the number of places to the right of the decimal point, the 3rd digit gives the number of spaces after the decimal point.

   FORMAT(' 123.456789',4,4) = ' 123.4567'
   FORMAT('12.34',5,4)       = '  12.3400'

Note that the number is always padded out with spaces if necessary. Note that sometimes it may be better to use TRUNC function.


TOP . . NEXT . . PREVIOUS . . SECTION INDEX . . FUNCTION-LIST . . HOME

3.2.6 The TRUNC Function

This function can be truncate a number so it has no (or only limited number of) decimal places.

   TruncatedNumber = TRUNC( Number, DecimalDigits  )

The 2nd argument can give the number of places to the right of the decimal point,

   TRUNC(' +0123.45678 ')  =  '123'
   TRUNC(' +0123.45678 ',2) =  '123.45'

Note that the number is always padded out with spaces if necessary. Note that it may be better to use FORMAT if you want to ensure the number is a specific length for output alignment.


TOP . . NEXT . . PREVIOUS . . SECTION INDEX . . FUNCTION-LIST . . HOME

3.2.7 The SIGN Function

This function will return either 1, -1 or 0 depending on whether the number is positive, negative or zero.

   SignOfNumber = SIGN( Number )

The function will fail if the input is not a number.

   SIGN('+12.7') =  '1'
   SIGN('0 ')     =  '0'
   SIGN('-235')   =  '-1'


TOP . . NEXT . . PREVIOUS . . SECTION INDEX . . FUNCTION-LIST . . HOME

3.2.8 The ABS Function

No, not some system to stop your program (joke), this function will always return a positive number. Negative numbers are converted to positive.

   AbsoluteValue = ABS( Number )

The function will fail if the input is not a number.

   ABS('-057') =  '57'
   ABS(' 0195')   = ' 0195'


TOP . . NEXT . . PREVIOUS . . SECTION INDEX . . FUNCTION-LIST . . HOME

3.2.9 The MIN & MAX Functions

These return either the highest or lowest number in a list.

   LargestNumber  = MAX( Number , Number , Number , etc  )
   SmallestNumber = MIN( Number , Number , Number , etc  )

Note that the numbers are separated by commas

   MAX( 1,2 ,3 ,4, 5, 6, 7 ) =  '7'
   MIN( 1,2 ,3 ,4, 5, 6, 7 ) =  '1'

Here's a program using MIN , MAX and RANDOM. Note that I've had to use INTERPRET because of the commas between the numbers.

   /*  REXX Number functions    */
   NumString = RANDOM(1,50)
   DO A = 1 TO 7
     NumString = NumString || "," RANDOM(1,50)
     END
               SAY 'Numstring ='  NumString
   INTERPRET  "SAY 'Highest   ='  MAX(" NumString ")"
   INTERPRET  "SAY 'Lowest    ='  MIN(" NumString ")"
   -------------------------
   Numstring = 25, 42, 28, 42, 10, 21, 23, 22
   Highest   = 42
   Lowest    = 10


TOP . . NEXT . . PREVIOUS . . SECTION INDEX . . FUNCTION-LIST . . HOME

3.2.10 The DATATYPE Function

This is a real goodie, it can be used two ways. One way gets used all the time (the second example here), this is when you just code one argument. You would use this when you don't know what a string contains, for example just after a PULL instruction. The function will either return NUM if the string contains a valid number or CHAR if it's not a number. Coding a second argument means the function will return a boolean number. '1' if the data in the input string matches the type you are looking for or '0' if it doesn't. Note the fact you can look for a whole number, when checking data this may be better than seeing if the result is 'NUM' . These are the options you can code.

      either BooleanNo = DATATYPE( String , Option )
      or     CHARorNUM = DATATYPE( String )
Options:
      A - Alphanumeric (A-Z,a-z,0-9) N - Valid Number
      B - Binary only (0,1)          U - Uppercase only (A-Z)
      L - Lower case only(a-z)       W - Whole Number
      M -Mixed case (A-Z, a-z)       X - Hexadecimal (0-9, A-E)
      S - Valid REXX Symbol(A-Z,a-z, 0-9 ! ? _ .)

Some Examples:

      DATATYPE('+123.4567')                         =  'NUM'
      DATATYPE('This is not a number.')             =  'CHAR'
      DATATYPE('Only4AlphanemericChars','a')        =  '1'
      DATATYPE('No spaces or specials!','Alphanum') =  '0'
      DATATYPE(SPACE('Include Spaces',0),'A')       =  '1'
      DATATYPE('onlylowercasechars','l')(Lowercase) =  '1'
      DATATYPE('MixedCaseCharacters','m')(Mixedcase)=  '1'
      DATATYPE('UPPERCASECHARACTERS','u')(Uppercase)=  '1'
      DATATYPE('Valid_REXX_Symbol','s)   (Symbol)   =  '1'
      DATATYPE('Not a Valid Symbol','s') (Symbol)   =  '0'
      DATATYPE('010101110010111010111','b')(Binary) =  '1'
      DATATYPE('A3b6C35689e2A9C4c905fff','x') (Hex) =  '1'
      DATATYPE('+123456.7890000000','n') (Number)   =  '1'
      DATATYPE('+123456','w')  (Whole number)       =  '1'


TOP . . NEXT . . PREVIOUS . . SECTION INDEX . . FUNCTION-LIST . . HOME

3.3 The CONVERSION Functions

These functions create a new string that represents the original string in a different format. Note: I've notice some platforms offer the functions X2B and B2X rather than C2B and B2C as shown here. Fancy having a function called X2C !!!

   C = Character, D = Decimal, X = Hexadecimal, B = Binary
   C2D('A')    =  '65'       C2D('AB')   =  '16706'
   C2D('0A'x)  =  '10'       C2X('A')    =  '41'
   C2X('AB')   =  '4142'     C2X('0A'x)  =  '0A'
   X2C('41')   =  'A'        X2C('4142') =  'AB'
   D2C('65')   =  'A'        D2C('16706')=  'AB'
   X2D('41')   =  '65'       X2D('4142') =  '16706'
   X2D('41'x)  =  '10'       C2B('A')    =  '01000001'
   B2C('01000001') =  'A'


TOP . . NEXT . . PREVIOUS . . SECTION INDEX . . FUNCTION-LIST . . HOME

3.4 BIT Functions

System programmers love these bits of bit functions. I've have noticed some variations on different platforms.

   C2B(BITOR('00010001'b,'01010101'b))  =  '01010101'
   C2X(BITOR('11'x,'55'x))              =  '55'
   C2B(BITXOR('00010001'b,'01010101'b)) =  '01000100'
   C2X(BITXOR('11'x,'55'x))             =  '44'
   C2B(BITAND('11110000'b,'00111100'b)) =  '00110000'
   C2X(BITAND('F0'x,'5C'x))             =  '50'


TOP . . NEXT . . PREVIOUS . . SECTION INDEX . . FUNCTION-LIST . . HOME

3.5 Programming Functions and Instructions

3.5.1 The SIGNAL instruction / CONDITION function

            CALL   ONorOFF condition NAME trapname
            SIGNAL ONorOFF condition NAME trapname
            CONDITION( Option ) = ConditionInfo

If you hit an un-recoverable error in your program you may want to use this to jump to a routine which is going to detail all the horrible things that have just happened (to create the error) before ending execution. The advantage of coding it in a separate routine is that it gets all the messages out of the main body of the program and also it may get called from one of several instructions. The S IGNAL ON condition can be used to say when you should jump to your error routine and what the routine is called (trapname). The 'condition' can be:

   ERROR - external command error   FAILURE - external command failure.
   HALT - on external halt request. NOVALUE - using an un-initialized variable.
   NOTREADY - i/o stream error      SYNTAX -  syntax or execution error.

The difference between S IGNAL and C ALL is that S IGNAL will not return you from the function it acts as a G OTO. Note that some of the conditions can not be used with C ALL. The C ONDITION function can be placed in an error sub-routine and it will give you some useful data about the error. Without an option it will say whether a CALL or a S IGNAL (not very exciting) involved the routine. An Option of ' C' returns the condition name, for example ' ERROR' or' N OVALUE'. An option of ' D' gives the type of trap. An option of ' I' returns ' SIGNAL' or ' CALL' depending on how the routine was requested. An option of ' S' returns the status of the trapped condition.


TOP . . NEXT . . PREVIOUS . . SECTION INDEX . . FUNCTION-LIST . . HOME

3.5.2 The SIGL variable & SOURCELINE function

               LineNoOfCALLorSignal  = SIGL
               SOURCELINE( LineNum ) = LineOfYourProgram
               SOURCELINE()          = TotalLines

When you execute an error function it may be useful to know which line of your program invoked the error which created the jump to the function. The variable SIGL is defined for you and gives you the line number. The SOURCELINE function can be used to print out that line of code. See the program in the next section for an example.


TOP . . NEXT . . PREVIOUS . . SECTION INDEX . . FUNCTION-LIST . . HOME

3.5.3 The RC variable & ERRORTEXT function

    ErrorType = RC
    ERRORTEXT( ErrorNumber ) = ErrorDescription

The RC variable is another one set for you and it gives the error code number. Unless you are very clever (in wish case you wont be reading this) this number is not much good but feed it as the argument to ERRORTEXT and it will give you a description of the error. See the example here:

   /* REXX Showing the SIGNAL instruction   */
   1   SIGNAL ON SYNTAX
   2   My_Result = 0
   3   IF MyResult THEN SAY "HELLO"
   4   EXIT 0
   5   SYNTAX:
   6   SAY "*** SYNTAX / EXECUTION  ERROR******"
   7   SAY "Line Number:"  SIGL
   8   SAY "The Line read '" || SOURCELINE(SIGL)"'"
   9   SAY "The Error was:'" || ERRORTEXT(RC)"'"
   10  SAY "(Total Lines): "    SOURCELINE()
   11  SAY "************************************"
   12  RETURN 0
OUTPUT----------------------------------------------
   *** SYNTAX / EXECUTION  ERROR******
   Line Number: 3
   The Line read 'IF MyResult THEN SAY "HELLO"'
   The Error was:'Boolean value not 0 or 1'
   (Total Lines):  16
   ************************************


TOP . . NEXT . . PREVIOUS . . SECTION INDEX . . FUNCTION-LIST . . HOME

3.5.4 The VALUE function

    ValueOfInString  = VALUE( InString , NewValue )

This is similar to the INTERPRET instruction. The template above InString is a variable that would contain the name of a 2nd variable. The function would return the contents of this second variable.

   /* REXX program to show VALUE() */
   A = 23
   B = A
   SAY VALUE(B)
   --------------------------------
   23


PREVIOUS . . SECTION INDEX . . FUNCTION-LIST . . HOME

3.5.5 The SYMBOL function

    VARorLITorBAD  = SYMBOL( InString )

I've never found this particularly useful! It will tell you if the contents of Instring is a valid variable name by returning V AR, a valid symbol name by returning LIT or BAD if its neither.


END OF FUNCTIONS

GOTO PARSE