# Operators

Once we know of the existence of variables, we can begin to operate with them. For that purpose, UnigineScript integrates operators. Operators are mostly made of signs that are not part of the alphabet but are available in all keyboards.

## Numerical Operators

OperationOperatorTypeDescriptionOperand Types
Negation-unaryReturns a negated value of the operand (changes its sign to the opposite) Scalars, vectors
Increment++unaryIncrements the operand by 1 (both prefix and postfix notations are supported)Scalars
Decrement--unaryDecrements the operand by 1 (both prefix and postfix notations are supported)Scalars
Multiplication*binaryMultiplies one operand by anotherScalars, vectors
Division/binaryDivides the first operand by the second operandScalars, vectors
Modulo%binary Returns a remainder after numerical division of the first operand by the second operand int, long, float and double
Subtraction-binarySubtracts the second operand from the first operandScalars, vectors

Source code(UnigineScript)
``````int a = 0, b = 0;
log.message("%d %d\n",++a,b++);
log.message("%d %d\n",++a,b++);
log.message("%d %d\n",a,b);

/* Output:
* 1 0
* 2 1
* 2 2
*/``````

### Scalar Operands

All numerical operators that take two operands of different types perform an automatic conversion of scalars. The result is always the biggest type of two.

### Vector Operands

Some of numerical operators are applicable to vector types. All vector types can be added to, subtracted from and multiplied by operands of the same type. However, when performing operations on different types of vector operands or vectors and scalars, only specific combinations of operands are possible, because vector types are mostly nonconvertible.

First operandOperatorSecond operandResult
All vector types:
vec3
vec4
dvec3
dvec4
ivec3
ivec4
mat4
dmat4
quat
+
-
*
The same as of the first operand Type of the operands
vec3
vec4
dvec3
dvec4
ivec3
ivec4
/ The same as of the first operand Type of the operands
All vector types:
vec3
vec4
dvec3
dvec4
ivec3
ivec4
mat4
dmat4
quat
*
/
int Type of the first operand
vec3
vec4
dvec3
dvec4
mat4
dmat4
quat
*
/
long
float
Type of the first operand
dvec3
dvec4
mat4
dmat4
quat
*
/
double Type of the first operand
vec3 *
/
double
dvec3
dvec3
vec4 *
/
double
dvec4
dvec4
vec3 +
-
dvec3 dvec3
vec4 +
-
dvec4 dvec4
dvec3 *
/
+
-
vec3 dvec3
dvec4 *
/
+
-
vec4 dvec4
mat4 * vec3
vec4
dvec3
dvec4
dmat4
Type of the second operand
mat4
dmat4
*quatType of the first operand
dmat4 * vec3
dvec3
dvec3
dmat4 * vec4
dvec4
dvec4
dmat4 *mat4dmat4
quat* vec3
vec4
dvec3
dvec4
mat4
dmat4
Type of the second operand

### String Operators

These operators take only string variables as operands.

OperationOperatorTypeDescription
Concatenation+binaryA string into which two operands are joined

Strings can be concatenated not only with strings but with variables of any base type due to type casting.

Source code(UnigineScript)
``````float a = -3.9;
string str = "there can be a mixture";
str = str + " of integer (" + 56 + ") and floating point values (" + a + ")";
log.message("%s\n", str);

/* Output:
* there can be a mixture of integer (56) and floating point values (-3.9)
*/``````

## Logical and Bitwise Operators

These operators take only the following types of variables as operands:

OperationOperatorTypeDescriptionOperand Types
Logical NOT!unaryNegates a boolean expression int, long
Logical AND&&binary true, if both operands are true int, long
Logical OR||binary true, if one or both operands are true int, long
Bitwise NOT (complement)~unaryLogical negation of each bit int, long
Bitwise AND&binaryLogical AND operation on each pair of corresponding bitsint, long
Bitwise inclusive OR|binaryLogical OR operation on each pair of corresponding bitsint, long
Bitwise exclusive OR^binaryLogical XOR operation on each pair of corresponding bitsint, long
Shift left<<binaryShift bit pattern in the first operand to the left by the number of bits specified by the second operand int, long
ivec3 or ivec4 can also be the 1st operand
Shift right>>binaryShift bit pattern in the first operand to the right by the number of bits specified by the second operand int, long
ivec3 or ivec4 can also be the 1st operand

All non-zero values are equal to true, however, if true should be returned as a result of some operation, it will be always 1. false is always 0.

Notice
When expressions with logical operators are evaluated, usually, short-circuit evaluation is used. That is, the second operand is only evaluated if the first operand does not suffice to determine the value of the whole expression. However, if the whole expression is enclosed in parentheses, all operands will be evaluated.

## Comparison Operators

Notice
Two float numbers are considered to be equal, if the difference between their values is less than 1E-6.

OperationOperatorDescriptionOperand Types
Equal to==Tests if both operands are equalScalars, vectors, string
int(0) can be compared to an empty string and v.v.
Not equal to!=Tests if both operands are not equalScalars, vectors, string
int(0) can be compared to an empty string and v.v.
Less than<Tests if the first operand is less than the the second operandScalars, string
Greater>Tests if the first operand is greater than the second operandScalars, string
Less than or equal to<=Tests if the first operand is less than the second operand or equal to itScalars, string
Greater than or equal to>=Tests if the first operand is greater than the second operand or equal to itScalars, string

If the statement is true, the operator returns 1, otherwise 0.

## Assignment Operators

OperationOperatorTypeDescription
Assignment=binaryAssign a value of the second operand to the first operand
"If-then-else" replacement? :ternaryCan be used for conditional assignment, if this whole expression is the second operand of the assignment

The conditional operator ?: can be used as a shorthand for what would normally be single-line blocks of the "if-then-else" construction. If used appropriately, this operator can enhance readability of code. Its syntax is the following: test_expression1 ? then_expression : else_expression.

Source code(UnigineScript)
``````int a = 10;
int b;
b = (a > 9) ? 100 : 200; // ternary operator usage

// this expression is equal to the previous one
if(a > 9) {
b = 100;
} else {
b = 200;
}
log.message("b =" + (b))
/* Output:
* b = 200
*/``````

It is also possible to use the ?: operator in expressions. For example:

Source code(UnigineScript)
``````int a = 1;
int b = 2;
int c = 3;
int d = 4;

log.message("%s\n","test 1: " + (a == b) ? "a == b" : "a != b" + " final");
log.message("%s\n","test 2: " + ((c == d) ? "c == d" : "c != d") + " final");
log.message("%s\n","test 3: " + (a == b) ? "a == b and " + ((c == d) ? "c == d" : "c != d") : ("a != b and " + ((c == d) ? "c == d" : "c != d")));``````
The output of the example is:
Output
``````test1: a != b final
test2: c != d final
test3: a != b and c != d``````

The assignment operator = can be combined with +, -, *, /, %, &, |, and ^. These combined operators (+=, -=, *=, /=, %=, &=, |=, and ^=) assign the result of the operation to the first operand (which must be a variable).

Notice
UnigineScript does not support multiple assignments in an expression:
Source code(UnigineScript)
``````int a = 10;
int b, c;
a = b = c; // this won't work
a = b += c; // this won't work either``````

## Access Operators

OperationOperatorTypeDescription
Member access.binaryAccess a member (the second operand) of the first operand. Can be used with:
Scope resolution::
• unary - for identifiers with the global scope
• binary - for identifiers with the class or namespace scope (class/namespace members).
Access an identifier outside its scope. For details, see scope resolution operator.
Access by index[]binary Access an element by it index. Can be used with classes, vectors, maps, vec3, vec4, mat4, and quat

## Type Testing Operator

The type testing operator is serves to check the type of a given variable. The operator returns 1 when:

• A given variable belongs to a specified type
• A given object is an instance of a specified class
• A given object is an instance of a class that derives from a specified class

The syntax of the operator is the following:

Source code(UnigineScript)
``i is int``

Notice
The second operand can only be the type or class name, namely:
• One of the scalar types
• One of the vector types
• String
• User-defined class name
• External class name

For example, this operator can be used in an if-else statement:

Source code(UnigineScript)
``````class Foo { };

class Bar : Foo { };

void check(int v) {
string s = typeinfo(v);
// both the is operator and the is_int() function check if v is of the int type
if(v is int) log.message("%s is int\n",s);
if(is_int(v)) log.message("%s is int\n",s);
// check if v is of the float type
if(v is float) log.message("%s is float\n",s);
if(is_float(v)) log.message("%s is float\n",s);
// check if v is an instance of the Stream class or class derived from the Stream
if(v is Stream) log.message("%s is Stream\n",s);
// check if v is an instance of the File class
if(v is File) log.message("%s is File\n",s);
// check if v is an instance of the Foo or Bar class
if(v is Foo) log.message("%s is Foo\n",s);
// check if v is an instance of the Bar class
if(v is Bar) log.message("%s is Bar\n",s);
}

check(1);
check(1.0f);
check(new File());
check(new Foo());
check(new Bar());``````
The output is the following:
Output
``````int: 1 is int
int: 1 is int
float: 1 is int
float: 1 is int
File 000000000E9330E0 internal (5:0:0) is Stream
File 000000000E9330E0 internal (5:0:0) is File
Foo 000000000D06FCD0 (131072:0:0) is Foo
Bar 000000000D06FD00 (196608:0:0) is Foo
Bar 000000000D06FD00 (196608:0:0) is Bar``````

## Operator Precedence

If an expression contains several operators, they will be evaluated in the order shown below, from the top to the bottom.

OperationOperator
Parentheses()
Access operators[] .
Unary operators! - + ++ --
Multiplicative operators* /
Bitwise shift<< >>
Comparison operators== != < > <= >=
Bitwise NOT~
Bitwise AND&
Bitwise exclusive OR^
Bitwise OR|
Logical NOT!
Logical AND&&
Logical OR||
Assignment operators= += -= *= /= %= &= |= ^= ?: