Arithmetic Operators

Math is an essential part of programming, and FreeBasic has a rich set of arithmetic operators available. The following table lists the arithmetic operators. The operators will work on two or more expressions, where expression is a number, variable or another expression. The square brackets in the syntax column indicate optional additional expressions.

Function Syntax Comment
+ (Addition) B = expression + expression [ + expression…] Returns the sum of two or more expressions. Expression can be a number, variable or another expression.
- (Subtraction) B = expression – expression [ - expression…] Returns the difference between two or more expressions.
* (Multiplication) B = expression * expression [ * expression…] Returns the product of two or more expressions.
/ (Division) B = expression / expression [ / expression…] Returns the division of two or more expression. The result implicitly converted to the target data type. That is, if B is an integer, the result will be rounded, if B is a double or single, the result will be a decimal number. If the second expression evaluates to zero (0), then a runtime error will occur.
\ (Integer Division) B = expression \ expression [ \ expression…] Returns the integer result of division of two or more expressions. The result is implicitly converted to an integer. If the second expression evaluates to zero (0), then a runtime error will occur.
^ (Exponentiation) B = expression^value Returns the result of raising expression to the power of value. That is 2^2 = 2*2.
MOD (Modulo) B = expression MOD expression Returns the remainder of the implicit division of the expressions as an integer result. If expression is a decimal value, expression is rounded before the division.
- (Negation) B = - expression Returns the negated value of expression. This is the same as multiplying by –1. If expression is positive, B will negative. If expression is negative, B will positive.
( ) (Parenthesis) B = expression operator ( expression [operator expression [ (…]) Forces evaluation of expression. Parenthesis can be nested, but must be closed properly or a compile error will occur.

You should be familiar with most of these operators from math class. Integer division is used when you are not concerned about the remainder of the division process. The Mod operator has several uses including executing some code only at certain times, and for creating wrap-around functions such as are likely to occur when a sprite reaches the edge of the screen and needs to wrap around to the other side.

When using these operators together in single statement, you must b aware of how FreeBasic evaluates the expression. For example, does 5 + 6 * 3 equal 33 or does it equal 23? FreeBasic evaluates expressions based on precedence rules, that is, rules that describe what gets evaluated when. The following table lists the precedence rules for the arithmetic operators. The order of precedence is the same order as the listing; that is the top row has the highest precedence, while lower rows have lower precedence.

Operator
( ) (Parenthesis)
^ (Exponentiation)
- (Negation)
*, / (Multiplication and division)
\ (Integer division)
MOD (Modulus)
SHL, SHR (Shift bit left and shift bit right)
+, - (Addition and subtraction)

Looking at the table and the equation 5 + 6 * 3 you can see that this will evaluate to 23 not 33, since multiplication has a higher precedence then addition. The compiler will read the expression from left to right, pushing values onto an internal stack until it can resolve part or all of the equation.

For this equation 5 will be read and pushed, then the + operator will be read and pushed onto the stack. Since the + operator requires two operands, the compiler will read the next element of the expression which will be the * operator. This operator also requires two operands, so * will be pushed onto the stack and the 3 will be read. Since * takes priority over +, the 6 and 3 will be multiplied, and that value will be stored on the stack. At this point there is a 5, + and 18 on the stack. Since there is only one operator and two operands, the 5 and 18 will be added together to make 23, which will be returned as the result of the expression.

If you wanted to make sure that 5 + 6 gets evaluated first, then you would use parenthesis to force the evaluation. You would write the parenthesized expression as (5 + 6) * 3. Since the parenthesis have the highest precedence, the expression they contain will be evaluated before the multiplication.

The evaluation process here is the same as the previous process. The ( is treated as an operator and is pushed onto the stack. The 5, +, and 6 are read followed by the ). The ) signals the end of the parenthesis operation, so the 5 and 6 are added together and pushed onto the stack. The * is read along with the 3. The stack at this point contains an 11, * and 3. The 11 and 3 are multiplied together and 33 is returned as the result of the evaluation.

You can also embed parenthesis within parenthesis. Each time the compiler encounters a (, it begins a new parenthesis operation. When it encounters a ), the last ( is used to evaluate the items contained within the ( and ) and that result is either placed on the stack for further evaluation or returned as a result. Each ( must be match to a ) or a compiler error will occur.

In the case where two operators are used that have the same precedence level, FreeBasic evaluates from left to right. 3 + 5 - 4 will evaluate to 4 since 3 + 5 is 8 and 8 - 4 is 4.

Shortcut Arithmetic Operators

FreeBasic has a number of shortcut arithmetic operators similar to those found in the C programming language. These operators have the same precedence as their single counterparts. The following table lists the shortcut operators.

Operator Syntax Comment
+= B += expression Add B to expression and assign to B.
-= B -= expression Subtract B from expression and assign to B.
*= B *= expression Multiply B with expression and assign to B.
/= B /= expression Divide B by expression and assign to B.
\= B \= expression Integer divide B by expression and assign to B.
^= B ^= expression Exponentiates B with expression and assigns to B.

Using these operators will cut down on the typing you have to do, especially for statements such as a = a + 1, which can be written as a += 1.

Binary Number System

Computers use the binary, or base 2, numbering system to represent data. Base 2 digits are the numbers 0 and 1. A single binary 1 or 0 is called a bit. Four bits is called a nybble. Two nybbles, or 8 bits is called a byte and 2 bytes make up a word. The size of a data type determines how many bits are available to represent a particular number. A byte has 8 bits, a short has 16 bits, an integer has 32 bits and a longint has 64 bits.

You will notice that each data type is double the size of the previous data type. This is because the binary system uses powers of 2 to represent data. 2^0 is 1. 2^1 is 2. 2^2 is 4. 2^3 is 8. 2^4 is 16, and so on. To find the value of a binary number, you start from the right, which is position 0 and add the power of twos going left if there is a 1 in the bit position.

If a nybble is 1101, then the right-most position is 2^0, the next position left is skipped since it has a zero, followed by 2^2 and finally 2^3. Resolving the power terms gives you 1 + 4 + 8 which equals 13. The value ranges for the different data types is a direct result of the number of bits in each data type.

Being able to manipulate individual bits, bytes and words has a number of uses. For example, the messaging system of the Windows API use integers to store both the id of a control and event the control received, as the following code snippet shows.

Case WM_COMMAND
   wmId    = Loword( wParam )
   wmEvent = Hiword( wParam )

In this snippet the id of the control is stored in the low word of wParam, and the event number is stored in the high word. Since a word is 2 bytes or 16 bits, you can store 65535 ids in a single word, using an unsigned data type, or 32767 ids for a signed data type. This is a very efficient way to manage data in your program.

The Sign Bit

The sign bit, the leftmost bit, is used by the computer to determine if a signed data type is negative or positive using the Two's Complement form of notation. To represent a negative number, the positive value of the number is negated, that is all the 1's are changed to 0 and the 0's are changed to 1's, and 1 is added to that result. For example, binary 5 is 0000 0101. Negating all the bits results in 1111 1010. Adding 1 results in 1111 1011. Since the leftmost bit is 1, this is a negative number.

We can confirm this by using the power of 2 notation which results in the following: −128 (2^7) + 64 (2^6) + 32 (2^5) + 16 (2^4) + 8 (2^3) + 0 + 2 (2^1) + 1 (2^0) = - 5. Remember, if a bit is zero, we add zero to the total.

This shows why signed data types have a smaller range of values than unsigned data types. A bit is being used to represent the sign of the number. If you are needing to store a large number of data values, such as ids, in a byte or integer, the number of possible values you can store depends on whether it is signed or unsigned. If the number of values needed exceed the range of a signed data type, then use an unsigned data type.