Previous chapter | Index | Next chapter |

BASIC functions and operators have been introduced so far in an order and to a depth designed to suit the reader who is entirely new to BASIC.

This chapter describes functions in a little more detail, gathered into logical groups, so you can easily appreciate what functions are provided in any particular area. It is probably not worth reading about facilities that don't sound relevant to your particular needs, especially if this is your first time working through this user guide; you can always return to them later.

This is not a complete description of the facilities available: the more complex or less usefule functions are either not described at all here, or are only described in outline. For further information on any of the functions and operators, see you will need to refer to 'Mallard BASIC: Introduction and Reference'

The facilities that you will use most frequently with numeric information have already been described: the arithmetic operators of addition (+), subtraction (-), multiplication (*) and division (/).

These operators all apply equally well to integers and floating point (single and double precision) arithmetic. There are two further operators, particularly suited to manipulating integers: \ which is used for integer division (it converts the numbers to integers before dividing and returns an integer result) and MOD, which returns the remainder after performing an integer division:

PRINT 7/2 3.5 PRINT 7\2 3 PRINT 7 MOD 2 1

To ensure that a number (expression, variable) is positive, use ABS. This converts a negative or positive number to a positive number of the same size.

To determine the sign of a number (expression, variable), use SGN. This returns 0 if the value is 0, -1 if it is negative, +1 if it is positive. This provides a convenient way of 'compressing' a value's range, for example:

100 state$(0) = "overdrawn" 110 state$(1) = "nil stock" 120 state$(2) = "in stock" ... 200 state = SGN(stock(item))+1 210 PRINT name$(item);" is ";state$(state)etc.

There are two logarithmic functions, providing natural logarithms (LOG) and logarithms to base 10 (LOG10).

To convert a natural logarithm back to the corresponding number, use EXP.

To raise a number to a power, use the exponentiation operator, . For example, to print 7 to the 4.4th power:

PRINT 7 4.4

To convert a logarithm to base 10 back to the corresponding number, use
10`x` (where
`x` is the logarithm).

**Note:** The
character is the exact equivalent to the
character used for the
exponentiation operator used on many CP/M systems. If you load a program developed on another
system and display it on the screen, any
characters it contains
will be shown as s. Similarly,
if you load a program developed on the Spectrum onto a different computer, the
s will be shown as
s.

BASIC provides three trigonometric functions, for converting angles (expressed in radians) into cosines, sines and tangents: COS, SIN and TAN. Each takes a single numeric argument, in brackets. For example:

opposite = adjacent*TAN(theta)

There is also a single function to convert a tangent to an angle (radians):

theta = ATN(opposite/adjacent)

You can, of couse, create further trigonometric functions from these three simple functions.
For example, if you need the cotangent of an angle, you can obtain this by putting
`1/TAN(theta)`

into your expression.

Yet more trigonometric functions can be produced with the help of the other BASIC functions introduced in this chapter. For details, see Appendix IX of 'Mallard BASIC: Introduction and Reference' - or any good mathematics book!

A number of operators are provided to manipulate integer numeric information at the level of individual bits. The most useful are:

`NOT`

`number`- invert each bit in the number
`number1`AND`number2`- set bits to 0 unless 1 in both numbers
`number1`OR`number2`- set bits to 0 unless 1 in either or both numbers
`number1`XOR`number2`- set bits to 0 unless 1 in one number, 0 in the other

These operators are often used in relational expressions, to invert the sense of a test, for example:

WHILE NOT EOF(file%) INPUT #file%,name$ WEND

It is occasionally useful to generate a number whose value you cannot easily predict - a 'random number'. This is often required in statistical analysis, when generating passwords, or programming games. It is very difficult to generate entirely random numbers. The BASIC function RND generates 'pseudorandom' numbers in the range 0...1: these numbers are in an entirely predictable, but rather obscure sequence which will be good enough for most purposes. In general, each time you use RND, you get the next number in the sequence.

So if, for example, you want a random number between 0 and 5, you could obtain this by using:

random.number = RND * 5

If you want to pick out the highest value from a list, use MAX. For example:

PRINT "The winner is";MAX(mark(1),mark(2),mark(3),mark(4))

If the values are negative, the highest is the one which is least negative.

Similarly, to pick out the lowest (most negative) number from a list, use MIN.

To change the whole of a string variable, you will usually use an equals sign:

new.string$= "New, new, new"

The alternative is to use the special keywords LSET and RSET. These assign one string to another in such a way that the length of the string is preserved by adding extra spaces either at the end of the string (LSET) or at the beginning (RSET). LSET and RSET are chiefly used to assign strings to the 'fields' of the records in a random access file. They are described in Chapter 6, on using disc files.

To change part of a string variable, use MID$ on the lefthand side of an assignment:

date$ = "xxxx March, 1989" MID$(date$,1,4) = "21st" PRINT date$ 21st March, 1989

The parameters to MID$ specify the string variable, the starting position and the number of characters to be replaced.

The only operator that can be used with strings is the addition operator '+', which adds the string to its right onto the end of the string to its left. Note that this is quite different to adding two numeric values - contrast the result of executing the two following instructions:

PRINT "123"+"456" PRINT 123+456

BASIC provides three functions to extract part of the text from a string: LEFT$, MID$ and RIGHT$.

- To extract the first
`n`characters from a string, use LEFT$(`string$`,`n`). - To extract the last
`n`characters from a string, use RIGHT$(`string$`,`n`). - To extract
`n`characters starting from position`s`from a string, use MID$(`string$`,`s`,`n`). (The first character in the string is at position 1.) - To extract all the characters starting from position
`s`from a string, use MID$(`string$`,`s`).

Two functions are provided to generate strings by repeating a single character.

To produce a string of `n` spaces, use SPACE$(`n`).

To produce a string of `n` characters with internal value c,
use STRING$(`n`, `c`).

To produce a string of `n` characters "`z`",
use STRING$(`n`, "`z`").

For example (where 42 is the internal value of *):

PRINT STRING$(20,"*");"Hi!";STRING$(20,42) ********************Hi!********************

A string can be anything from 0 to 255 characters long. BASIC provides a
function, LEN, that returns the length of the string that is its argument.
This is particularly useful when you need to process the string a character
at a time, such as in the following routine, which displays the string in
`title$`

double-spaced across the screen:

100 characters = LEN(title$) 110 FOR a = 1 TO characters 120 PRINT MID$(title$,a,1);" "; 130 NEXT 140 PRINT

To check whether a string contains a particular sequence of characters, you can use INSTR. This takes the form:

INSTR([start,]string1$,string2$)

`Start` specifies where the string is to be searched from; if this is omitted or
set to 1, the whole string will be searched.

`String1$` is the string to search. `String2$` is the string to search for
in `string1$`

INSTR returns a numeric result. If the result is 0 then `string2$` was not found
in `string1$`. Otherwise, the result returned is the position in `string1$`
of the first occurrence of `string2$` at or after the `start`.

This function has a number of uses not immediately apparent. For example, in the following it is used to cater for the user typing options as upper or lower case letters:

... 100 PRINT "A=abort, B=begin again, R=retry. Press a key." 110 answer$ = INKEY$ 120 IF answer$ = "" THEN 110 130 code = INSTR(1,"AaBbRr",answer$) 140 IF code = 0 THEN GOTO 100 150 ON code GOSUB 500,500,600,600,900,900

Text strings, unlike keywords, will be stored as upper and lower case if that is how they are typed. BASIC provides two functions to convert strings from upper case (capitals) to lower case and vice versa.

To convert a string to all upper case, use UPPER$(`string$`). To convert a string
to all lower case, use LOWER$(`string$`). For example:

PRINT UPPER$("February 1989 Accounts BOOK") FEBRUARY 1989 ACCOUNTS BOOK

Note that this conversion does not affect any symbols other than the letters 'a'-'z' or 'A'-'Z'.

Characters in text strings can have internal values in the range 0 to 255, but only
characters 0-127 are defined by the ASCII standard. You may occasionally need to use
strings in which the top bit has been set (for example, as a parity bit) but should now
be ignored: use STRIP$(`string$`) to ensure that you are only using codes in the
range 0 to 127.

This section describes the functions provided to convert information between the four main forms in which it is stored: string, integer, single and double precision.

Many conversions are performed automatically - for instance, an integer value can simply be assigned to a double precision variable, or a double precision value to an integer variable without using any conversion function. There are two main reasons for using conversion functions: to convert between incompatible data types (numeric and string) and to force a particular conversion when it would not normally occur.

The function ASC returns the internal value for a given character, so that
`PRINT ASC("A")` would print `65`.

The function CHR$ returns the character with a particular internal value,
so that `PRINT CHR$(65)` would print A.

Although numeric values are converted to the text equivalent automatically when printed, you cannot use strings as numbers or vice versa. To use a string (such as "1234") as a number, or a number (such as 1234) as a string, you must use a conversion function.

To convert a number to exactly the same representation as would be used to
print it, use STR$, for example: `number$ = STR$(number)`

To convert a text representation of a number to a number, use VAL, for
example: `number = VAL(number$)`

Other functions are provided to convert numeric values to decimal, octal and hexadecimal strings. These are described in 'Mallard BASIC: Introduction and Reference'.

Other functions are also provided to convert numeric values to and from compact string representations for use with disc data files. These are described in Section 6.3.

When a numeric value of one type is assigned to a numeric variable of a different type, it is automatically converted to suit the new type. However, there are two occasions when you may want to use conversion functions: when the numeric value is not being assigned to a variable so conversion would not normally take place, and when the conversion that would take place is not as you want.

When assigning a floating point value to an integer, the value will normally be rounded to the nearest integer with the integer further away from zero being chosen in the case of a tie. Thus 4.5 would round to 5, while 4.49 would round to 4.

To convert a numeric value to integer, single or double precision (as if assigning it to a variable of that type), use CINT, CSNG or CDBL respectively. This may be needed to force an expression to be evaluated in a particular precision; for example, compare:

Type | a# = 1/10 |
with | Type | a# = CDBL(1)/10 |

Type | PRINT a# |
Type | PRINT a# | |

0.1000000014901161 |
0.1 |

In the first case the division is performed using single length arithmetic
giving a single length result, which is then converted to double length when
it is assigned to the double length variable `a#`. In the second case
the CDBL in the expression converts the dividend to double length before the
division, which means that the division is performed using double length
arithmetic, giving a double length result. (Incidentally, the first case
illustrates the inexact representation of decimal fractions as binary ones, by
printing the single length value of 0.1 to sixteen decimal digits rather than
the usual seven.)

Functions are also provided to round the floating point part of a number in other ways. These are INT, FIX and ROUND. The number remains floating point.

To round a number to the smaller integer, use `INT`.
`INT(3.9)` will produce 3, while `INT(-3.9)` will produce
-4.

To round a number simply by losing the decimal part, use `FIX`.
`FIX(3.9)` will produce 3, while `FIX(-3.9)` will produce
-3.

To round a number to a specified number of decimal places, use
`ROUND( number,places)`. For example,

If `places` is negative, it is taken as the number of digits to
round to the left of the decimal place; for example,
`ROUND(12345,-2)` gives 12300.

Previous chapter | Index | Next chapter |