# Retroprogramming by spotlessmind1975

### Site Tools

ugbasic:user:maths

# ugBASIC User Manual

## MATHS

This section provides a full explanation of using standard mathematical and trigonometric functions, as well an insight into how ugBASIC exploits numbers.

### Arithmetical calculations

Traditional mathematical operation is very easy on ugBASIC, since it gives to the programmer all basic arithmetical operations. For example, this instruction will print out a simple `4` as a result:

` DEBUG 2+2`

ugBASIC recognize various mathematical symbols, as follows:

• `+` the plus sign that always signals addition;
• `-` the minus sign, used for subtraction;
• `*` the asterisk sign for multiplication;
• `/` the forward-slash symbol for division.
• `^` the circumflex character as exponential symbol (raise this number to a given power);

The following two lines are equal:

```  a = 3^5
b = 3*3*3*3*3```

The following logical operations can also be used in calculations:

• `MOD` is the “modulo” operator, which acts as a constant multiplier.
• `AND` is the logical and;
• `OR` is the logical or;
• `XOR` is the logical exclusive or.

### Calculation priorities

Since arithmetical instructions are taken literally, ugBASIC uses a set of built-in priorities. So the following lines give the results 6 and 8, respectively:

``` DEBUG 2+2*2 : REM Print 6
DEBUG (2+2)*2 : REM Print 8```

ugBASIC handles a combination of calculations that make up an “expression” in the following strict order of priority:

• exponential (`^`) are always calculated first ;
• multiplications (`*`) and divisions (`/`) are then calculated in order of appearance, from left to right;
• the the modulo operations (`MOD`) is elaborated;
• additions (`+`) and subtractions (`-`) are calculated last, again in order, from left to right.

Logical operations will not be taken into account until after all the above calculations have been completed (AND, OR, XOR). Obviously, any calculation placed inside a pair of round brackets is evaluated first, and treated as a single number. So the next calculation gives a result of 43:

` DEBUG 10+2*5-8/4+5^2 : REM Print 43`

This is the order followed:

``` 5^2 = 25
2*5 = 10
8/4 = 2
10+10 = 20
20-2 = 18
18+25 = 43```

By adding two strategic pairs of brackets to the same calculation, the logical interpretation is transformed, resulting in an answer of 768 (!), like this:

` DEBUG (10+2)*(5-8/4+5)^2 : REM Print 768`

This is the different order followed:

``` 10+2 = 12
5-8/4+5 = 5-2+5
5-2+5 = 8
8^2 = 64
12*64 = 768```

### Fast calculations

There are three instructions that can be used to increase the speed when it is present a simple calculation:

• `INC` to increment a variable by 1
• `DEC` to decrement a variable by 1
• `ADD` to add any number to a variable

`INC` command adds 1 to an variable, using a single instruction to perform the expression `variable=variable+1` very quickly. For example:

`  v=41 : INC v : DEBUG v`

Similarly to `INC`, the `DEC` command performs a rapid subtraction of 1 from an integer variable.

`  v=43 : DEC v : DEBUG v`

Finally, the `ADD` command can be used to add the result of an expression to a whole number variable. It is the equivalent to make a `variable=variable+expression` but performs the addition faster. There is a more complex version of `ADD`, which is ideal for handling certain loops much more quickly than the equivalent separate instructions. When those other parameters are included, `ADD v,a,b TO t` is the equivalent to the following lines:

```  v=v+a
IF v<b THEN v=t: ENDIF
IF v>t THEN v=b: ENDIF```

Here is an example:

```  v=0
REPEAT
DEBUG v
UNTIL v == 43 : REM This loop is infinite because v < 43```

### Relative values

It is obvious that every expression has a value, but expressions are not restricted to whole numbers (integers), or any sort of numbers. Expressions can be created from real numbers or strings of characters. If you need to compare two expressions, the following functions are provided to examine them and establish their relative values.

`MAX` compares two expressions and returns the largest. It can be used with any type of expressions, but they cannot be compared if they are mixed.

``` DEBUG MAX(99,1) : REM Print a 99
DEBUG MAX("ugBASIC","AAAA") : REM Print "ugBASIC"```

On the very same way, `MIN` compares two expressions and returns the smaller value of two expressions.

``` DEBUG MIN(99,1) : REM Print a 1
DEBUG MIN("ugBASIC","AAAA") : REM Print "AAAA"```

### Values and signs

To explain how ugBASIC treats signed numbers, it is necessary to make a brief excursus on the concept of “two's complement”. There are 256 possible values in a byte: \$00 to \$FF. The range of an 8-bit unsigned number is 0 (\$00) to 255 (\$FF). The range of a 16-bit unsigned number is 0 (\$0000) to 65535 (\$FFFF), and so on. They are called unsigned numbers because they are zero or greater, i.e. there is no (minus) sign.

A signed number, on the other hand, can be negative or positive (or zero). The term “signed number” is used below to mean a twos complement number, so the range of an 8-bit signed number is -128 to 127. The values -128 through -1 are, in hex, \$80 through \$FF, respectively. The values 0 through 127 are, in hex, \$00 through \$7F, respectively. So the minimum value of a signed number is \$80 and the maximum value of a signed number is \$7F. The range of a 16-bit signed number is -32768 (\$8000) to 32767 (\$7FFF) (\$8000 through \$FFFF are the negative numbers), and so on.

This may seem like a strange way of handling negative numbers, but this method has several useful properties:

• same representation for positive numbers: the “overlap” of the ranges of 8-bit signed and unsigned numbers is, in hex, \$00 to \$7F, regardless of whether the number is signed or unsigned;
• a bit for the sign : the most significant bit (bit 7 for an 8-bit number) is zero when the number is non-negative (0 to 127), and one when the number is negative;
• zero is positive: in mathematics, zero is not a postive or a negative number, but in the computer world, things are less formal; so the term “positive number” typically includes zero because (a) all of the other possible values of a signed number whose most significant bit is zero are positive numbers, and (b) all of the other possible values for an unsigned number are positive numbers.
• adding and subtracting is the same.

Any number can have one of three values: negative, positive or zero, and these are represented by the “sign” of a number. So the `SGN` function returns a value representing the sign of a number. The three possible results are these:

• -1 if the value is negative
• 1 if the value is positive
• 0 if the value is zero
`  DEBUG SGN(-42): REM Print -1`

On the other side, `ABS` can be used to convert arguments into a positive number. ABS returns an absolute value of an integer or fractional number, paying no attention to whether that number is positive or negative, in other words, ignoring its sign.

```  DEBUG ABS(-1): REM Print 1
DEBUG ABS(1): REM Print 1```

### Random numbers

The easiest way to introduce an element of chance or surprise into a program is to throw some numbered options into an electronic “pot” and to allow ugBASIC to pull one out at random. After a number has been selected and used, it is thrown back into the pot once again. It then has the same chance as any other number offered for selection, when the next random choice is made.

The `RND` function generates integers at random, between zero and any number specified in brackets. If your specified number is greater than zero, random numbers will be generated up to that maximum number. However, if you specify 0, then `RND` will return the last random value it generated. This is useful for debugging programs.

```DO
x = RND(WIDTH): REM you can use "RANDOM WIDTH" as an alternative
y = RND(HEIGHT-1): REM you can use "RANDOM HEIGHT" as an alternative
TEXT x, y, "UGBASIC AT RANDOM"
LOOP```

In practice, the numbers produced by the `RND` function are not genuinely random at all. They are computed by an internal mathematical formula, whose starting point is taken from a number known as a “seed”. This seed is set to a standard value whenever ugBASIC is loaded into your computer, and that means that the sequence of numbers generated by the `RND` function will be exactly the same each time your program is run.

This may well be acceptable for arcade games, where pre-set random patterns generated by `RND` can be used to advantage, but it is a useless system for more serious applications. The `RANDOMIZE` command solves this problem by setting the value of the seed directly. This seed can be any value you choose, and each seed will generate an individual sequence of numbers. `RANDOMIZE` can also be used in conjunction with the `TIMER` variable, to generate genuine random numbers.

The `TIMER` reserved variable is incremented by 1 unit every 50th of a second, in other words, it returns the amount of time that has elapsed since your computer was last switched on. As explained above, this makes it a perfect “seed” to be used with the `RANDOMIZE` function, as follows:

`  RANDOMIZE TIMER`

The best place to use this technique is immediately after the user has entered some data into the computer. Even a simple key-press to start a game will work perfectly, and generate truly random numbers.

### Page Tools 