User Tools

Site Tools


ugbasic:user:maths
Translations of this page:


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
     ADD v,1,1 TO 42
     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.