Variables and Types

Variables declaration

To declare a variable in PureBasic, simply type its name. You can also specify the type you want this variable to be. By default, when a data type is not indicated, the data is an integer. Variables do not need to be explicitly declared, as they can be used as "variables on-the-fly". The Define keyword can be used to declare multiple variables in one statement. If you don't assign an initial value to the variable, their value will be 0.

Example

  a.b         ; Declare a variable called 'a' from byte (.b) type.
  c.l = a*d.w ; 'd' is declared here within the expression and it's an integer !
Notes:
Variable names must not start with a number (0,1,...), contain operators (+,-,...) or special characters (,,,,...).

The variables in PureBasic are not case sensitive, so "pure" and "PURE" are the same variable.

If you don't need to change the content of a variable during the program flow (e.g. you're using fixed values for ID's etc.), you can also take a look at constants as an alternative.

To avoid typing errors etc. it's possible to force the PureBasic compiler to always want a declaration of variables, before they are first used. Just use EnableExplicit keyword in your source code to enable this feature.

Basic types

PureBasic allows many type variables which can be standard integers, float, double, quad and char numbers or even string characters. Here is the list of the native supported types and a brief description :

Name
Extension
Memory consumption
Range
Byte .b 1 byte -128 to +127
Ascii .a 1 byte 0 to +255
Character .c 1 byte (in ascii mode and only with compiler 5.4x and below) 0 to +255
Character .c 2 bytes (in unicode mode) 0 to +65535
Word .w 2 bytes -32768 to +32767
Unicode .u 2 bytes 0 to +65535
Long .l 4 bytes -2147483648 to +2147483647
Integer .i 4 bytes (using 32-bit compiler) -2147483648 to +2147483647
Integer .i 8 bytes (using 64-bit compiler) -9223372036854775808 to +9223372036854775807
Float .f 4 bytes unlimited (see below)
Quad .q 8 bytes -9223372036854775808 to +9223372036854775807
Double .d 8 bytes unlimited (see below)
String .s string length + 1 unlimited
Fixed String .s{Length} string length unlimited

Unsigned variables: Purebasic offers native support for unsigned variables with byte and word types via the ascii (.a) and unicode (.u) types. The character (.c) type is an unsigned word in unicode that may be used as an unsigned type.

Notation of string variables: it is possible to use the '$' as last char of a variable name to mark it as string. This way you can use 'a$' and 'a.s' as different string variables. Please note, that the '$' belongs to the variable name and must be always attached, unlike the '.s' which is only needed when the string variable is declared the first time.
  a.s = "One string"
  a$ = "Another string"
  Debug a   ; will give "One string"
  Debug a$  ; will give "Another string"

Note: The floating numbers (floats + doubles) can also be written like this: 123.5e-20
  value.d = 123.5e-20
  Debug value   ; will give 0.000000000000000001235

Operators

Operators are the functions you can use in expressions to combine the variables, constants, and whatever else. The table below shows the operators you can use in PureBasic, in no particular order (LHS = Left Hand Side, RHS = Right Hand Side).

Operator
Description / Example
=
Equals. This can be used in two ways. The first is to assign the value of the expression on the RHS to the variable on the LHS. The second way is when the result of the operator is used in an expression and is to test whether the values of the expressions on the LHS and RHS are the same (if they are the same this operator will return a true result, otherwise it will be false).

Example:
a=b+c ; Assign the value of the expression "b+c" to the variable "a"
If abc=def ; Test if the values of abc and def are the same, and use this result in the If command


When using with strings the '=' is used as assigning operator as well as operator for comparing. Note: the comparing of two strings is "Case-sensitive".

Example:
a$ = b$ ; Assign the content of the string "b$" to the string "a$" zu
If a$ = b$ ; Test, if the content of the strings a$ and b$ is equal, and use this result in the If command.
+
Plus. Gives a result of the value of the expression on the RHS added to the value of the expression on the LHS. If the result of this operator is not used and there is a variable on the LHS, then the value of the expression on the RHS will be added directly to the variable on the LHS.

Example:
number=something+2 ; Adds the value 2 to "something" and uses the result with the equals operator
variable+expression ; The value of "expression" will be added directly to the variable "variable"


With strings the '+' is also valid for combining the contents of two strings, where the result will be assigned to the string on the LHS with the '=' operator or will be directly stored into the string on the LHS. Numeric values are also accepted for combination with a string. It will behave like using Str(), Str() or StrD() with their defaults for the optional parameters.

Example:
a$ = b$ + " more" ; Combines the content of the string "b$" with the string " more" and save this into the string "a$"
a$ + b$ ; Attach the content of the string b$ directly to the string a$. a$ = b$ + 123
-
Minus. Subtracts the value of the expression on the RHS from the value of the expression on the LHS. When there is no expression on the LHS this operator gives the negative value of the value of the expression on the RHS. If the result of this operator is not used and there is a variable on the LHS, then the value of the expression on the RHS will be subtracted directly from the variable on the LHS. This operator cannot be used with string type variables.

Example:
var=#MyConstant-foo ; Subtracts the value of "foo" from "#MyConstant" and uses the result with the equals operator
another=another+ -var ; Calculates the negative value of "var" and uses the result in the plus operator
variable-expression ; The value of "expression" will be subtracted directly from the variable "variable"
*
Multiplication. Multiplies the value of the expression on the LHS by the value of the expression on the RHS. If the result of this operator is not used and there is a variable on the LHS, then the value of the variable is directly multiplied by the value of the expression on the RHS. This operator cannot be used with string type variables.

Example:
total=price*count ; Multiplies the value of "price" by the value of "count" and uses the result with the equals operator
variable*expression ; "variable" will be multiplied directly by the value of "expression"
/
Division. Divides the value of the expression on the LHS by the value of the expression on the RHS. If the result of this operator is not used and there is a variable on the LHS, then the value of the variable is directly divided by the value of the expression on the RHS. This operator cannot be used with string type variables.

Example:
count=total/price ; Divides the value of "total" by the value of "price" and uses the result with the equals operator
variable/expression ; "variable" will be divided directly by the value of "expression"
&
Bitwise AND. You should be familiar with binary numbers when using this operator. The result of this operator will be the value of the expression on the LHS anded with the value of the expression on the RHS, bit for bit. The value of each bit is set according to the table below. Additionally, if the result of the operator is not used and there is a variable on the LHS, then the result will be stored directly in that variable. This operator cannot be used with strings.
LHS | RHS | Result
------------------
 0  |  0  |    0
 0  |  1  |    0
 1  |  0  |    0
 1  |  1  |    1
Example:
; Shown using binary numbers as it will be easier to see the result
a.w = %1000 & %0101 ; Result will be 0
b.w = %1100 & %1010 ; Result will be %1000
bits = a & b ; AND each bit of a and b and use result in equals operator
a & b ; AND each bit of a and b and store result directly in variable "a"
|
Bitwise OR. You should be familiar with binary numbers when using this operator. The result of this operator will be the value of the expression on the LHS or'ed with the value of the expression on the RHS, bit for bit. The value of each bit is set according to the table below. Additionally, if the result of the operator is not used and there is a variable on the LHS, then the result will be stored directly in that variable. This operator cannot be used with strings.
LHS | RHS | Result
------------------
 0  |  0  |    0
 0  |  1  |    1
 1  |  0  |    1
 1  |  1  |    1
Example:
; Shown using binary numbers as it will be easier to see the result
a.w = %1000 | %0101 ; Result will be %1101
b.w = %1100 | %1010 ; Result will be %1110
bits = a | b ; OR each bit of a and b and use result in equals operator
a | b ; OR each bit of a and b and store result directly in variable "a"
!
Bitwise XOR. You should be familiar with binary numbers when using this operator. The result of this operator will be the value of the expression on the LHS xor'ed with the value of the expression on the RHS, bit for bit. The value of each bit is set according to the table below. Additionally, if the result of the operator is not used and there is a variable on the LHS, then the result will be stored directly in that variable. This operator cannot be used with strings.
LHS | RHS | Result
------------------
 0  |  0  |    0
 0  |  1  |    1
 1  |  0  |    1
 1  |  1  |    0
Example:
; Shown using binary numbers as it will be easier to see the result
a.w = %1000 ! %0101 ; Result will be %1101
b.w = %1100 ! %1010 ; Result will be %0110
bits = a ! b ; XOR each bit of a and b and use result in equals operator
a ! b ; XOR each bit of a and b and store result directly in variable "a"
~
Bitwise NOT. You should be familiar with binary numbers when using this operator. The result of this operator will be the not'ed value of the expression on the RHS, bit for bit. The value of each bit is set according to the table below. This operator cannot be used with strings.
RHS | Result
----------
 0  |    1
 1  |    0
Example:
; Shown using binary numbers as it will be easier to see the result
a.b = ~%1000 ; In theory the result will be %0111 but in fact is %11110111 (= -9 because a byte is signed).
b.b = ~%1010 ; In theory the result will be %0101 but in fact is %11110101 (= -11 because a byte is signed)
()
Brackets. You can use sets of brackets to force part of an expression to be evaluated first, or in a certain order.

Example:
a = (5 + 6) * 3 ; Result will be 33 since the 5+6 is evaluated first
b = 4 * (2 - (3 - 4)) ; Result will be 12 since the 3-4 is evaluated first, then the 2-result, then the multiplication
<
Less than. This is used to compare the values of the expressions on the LHS and RHS. If the value of the expression on the LHS is less than the value of the expression on the RHS this operator will give a result of true, otherwise the result is false.

Example:
If a < b ; Tests, if the value a is smaller than b, and uses this result in the If command

Note: The comparing of strings will always be "case-sensitive".
>
More than. This is used to compare the values of the expressions on the LHS and RHS. If the value of the expression on the LHS is more than the value of the expression on the RHS this operator will give a result of true, otherwise the result is false.

Example:
If a > b ; Tests, if the value a is greater than b, and uses this result in the If command

Note: The comparing of strings will always be "case-sensitive".
<=
=<
Less than or equal to. This is used to compare the values of the expressions on the LHS and RHS. If the value of the expression on the LHS is less than or equal to the value of the expression on the RHS this operator will give a result of true, otherwise the result is false.
>=
=>
More than or equal to. This is used to compare the values of the expressions on the LHS and RHS. If the value of the expression on the LHS is more than or equal to the value of the expression on the RHS this operator will give a result of true, otherwise the result is false.
<>
Not equal to. This is used to compare the values of the expressions on the LHS and RHS. If the value of the expression on the LHS is equal to the value of the expression on the RHS this operator will give a result of false, otherwise the result is true.
And
Logical AND. Can be used to combine the logical true and false results of the comparison operators to give a result shown in the following table.
  LHS  |  RHS  | Result
-----------------------
 false | false | false
 false |  true | false
  true | false | false
  true |  true |  true
Or
Logical OR. Can be used to combine the logical true and false results of the comparison operators to give a result shown in the following table.
  LHS  |  RHS  | Result
-----------------------
 false | false | false
 false |  true |  true
  true | false |  true
  true |  true |  true
XOr
Logical XOR. Can be used to combine the logical true ot false results of the comparison operators to give a result shown in the following table. This operator cannot be used with strings.
  LHS  |  RHS  | Result
-----------------------
 false | false | false
 false |  true |  true
  true | false |  true
  true |  true | false
Not
The result of this operator will be the not'ed value of the logical on the RHS. The value is set according to the table below. This operator cannot be used with strings.
  RHS  | Result
---------------
 false |  true
  true | false
<<
Arithmetic shift left. Shifts each bit in the value of the expression on the LHS left by the number of places given by the value of the expression on the RHS. Additionally, when the result of this operator is not used and the LHS contains a variable, that variable will have its value shifted. It probably helps if you understand binary numbers when you use this operator, although you can use it as if each position you shift by is multiplying by an extra factor of 2.

Example:
a=%1011 << 1 ; The value of a will be %10110. %1011=11, %10110=22
b=%111 << 4 ; The value of b will be %1110000. %111=7, %1110000=112
c.l=$80000000 << 1 ; The value of c will be 0. Bits that are shifted off the left edge of the result are lost.
>>
Arithmetic shift right. Shifts each bit in the value of the expression on the LHS right by the number of places given by the value of the expression on the RHS. Additionally, when the result of this operator is not used and the LHS contains a variable, that variable will have its value shifted. It probably helps if you understand binary numbers when you use this operator, although you can use it as if each position you shift by is dividing by an extra factor of 2.

Example:
d=16 >> 1 ; The value of d will be 8. 16=%10000, 8=%1000
e.w=%10101010 >> 4 ; The value of e will be %1010. %10101010=170, %1010=10. Bits shifted out of the right edge of the result are lost (which is why you do not see an equal division by 16)
f.b=-128 >> 1 ; The value of f will be -64. -128=%10000000, -64=%11000000. When shifting to the right, the most significant bit is kept as it is.
%
Modulo. Returns the remainder of the RHS by LHS integer division.

Example:
a=16 % 2 ; The value of a will be 0 as 16/2 = 8 (no remainder)
b=17 % 2 ; The value of a will be 1 as 17/2 = 8*2+1 (1 is remaining)

Operators shorthands

Every math operators can be used in a shorthand form.

Example

  Value + 1  ; The same as: Value = Value + 1
  Value * 2  ; The same as: Value = Value * 2
  Value << 1 ; The same as: Value = Value << 1
Note: this can lead to 'unexpected' results is some rare cases, if the assignment is modified before the affection.

Example

  Dim MyArray(10)
  MyArray(Random(10)) + 1 ; The same as: MyArray(Random(10)) = MyArray(Random(10)) + 1, but here Random() won't return the same value for each call.

Operators priorities

  Priority Level |     Operators
  ---------------+---------------------------
       8 (high)  |         ~, - (negative)
       7         |      <<, >>, %, !
       6         |         |, &
       5         |         *, /
       4         |         +, - (substraction)
       3         | >, >=, =>, <, <=, =<, =, <>
       2         |          Not
       1 (low)   |      And, Or, XOr

Structured types

Build structured types, via the Structure keyword. More information can be found in the structures chapter.

Pointer types

Pointers are declared with a '*' in front of the variable name. More information can be found in the pointers chapter.

Special information about Floats and Doubles

A floating-point number is stored in a way that makes the binary point "float" around the number, so that it is possible to store very large numbers or very small numbers. However, you cannot store very large numbers with very high accuracy (big and small numbers at the same time, so to speak).

Another limitation of floating-point numbers is that they still work in binary, so they can only store numbers exactly which can be made up of multiples and divisions of 2. This is especially important to realize when you try to print a floating-point number in a human readable form (or when performing operations on that float) - storing numbers like 0.5 or 0.125 is easy because they are divisions of 2. Storing numbers such as 0.11 are more difficult and may be stored as a number such as 0.10999999. You can try to display to only a limited range of digits, but do not be surprised if the number displays different from what you would expect!

This applies to floating-point numbers in general, not just those in PureBasic.

Like the name says the doubles have double-precision (64-bit) compared to the single-precision of the floats (32-bit). So if you need more accurate results with floating-point numbers use doubles instead of floats.

The exact range of values, which can be used with floats and doubles to get correct results from arithmetic operations, looks as follows:
Float: +- 1.175494e-38 till +- 3.402823e+38
Double: +- 2.2250738585072013e-308 till +- 1.7976931348623157e+308
More information about the 'IEEE 754' standard you can get on Wikipedia.