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. 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 !
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)         | 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 byte in ascii and 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 = (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

Operator + (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"

Operator - (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"

Operator * (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"

Operator / (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"

Operator & (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"

Operator | (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"

Operator ! (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"

Operator ~ (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.w = ~%1000 ; Result will be %0111
  b.w = ~%1010 ; Result will be %0101

Operator () (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

Operator < (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.

Operator > (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.

Operator <= (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.

Operator >= (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.

Operator <> (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.

Operator 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

Operator 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

Operator XOr (Logical XOR)

Can be used to combine the logical true and 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

Operator Not (Logical 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

Operator << (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=$8000000 << 1 ; The value of c will be 0. Bits that are shifted off the left edge of the result are lost.

Operator >> (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.

Operator % (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 priorities

  Priority Level |     Operators
  ---------------+---------------------
       8 (high)  |      ~, -
       7         |    <<, >>, %, !
       6         |       |, &
       5         |       *, /
       4         |       +, -
       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.