# Arithmetic & Logical Expressions

Oxygene allows the use of operators to create comparisons, arithmetic expressions and logic expressions. The language has well-defined set of operators for these scenarios, but Types can provide custom implementations for operators, using a technique called Custom Operators, a.k.a. Operator Overloading.

## Comparisons

Supported Operators: `=`, `≠`, `<`, `≤`, `>`, `≥` (and `<=`, `>=`, `<>`)

The above operators can be used to compare two operands for equality, non-equality and sort order.

For types that to not provide a custom equality and/or non-equality operator implementation, `=` and `≠` will compare the object reference (i.e. identity) of heap based types (such as Classes), and do a memory/value compare for stack-based types (such as Integers, Booleans, Floats, and Records).

If a matching custom `=` or `≠` operator is defined on the type of either the left or the right-hand expression, it will be called instead.

The `<`, `≤`, `>`, `≥` operators are only supported if the appropriate custom operator is implemented on one of the types.

``````var x := 5;
var y := 10;
if x ≤ 5 then ...
``````

Note : Oxygene supports rich unicode `≤`, `≥` and `≠` operators, but also, for backwards compatibility, the double-character `<=`, `>=` and `<>` spelling. Fire and Water will auto-correct `<=`, `>=` and `!=` to `≤`, `≥` and `≠`, respectively, and on macOS you can use ⌥<, ⌥> and ⌥= to type these operators directly, as well.

## Double Boolean Comparisons

Oxygene provides a convenient short-hand for comparing a value against two boundaries at once, via Double Boolean Comparisons. a double boolean comparisons is true only of both the first and the second hald of the expression is true. It is convenient for testing if a value falls within a range between two values:

``````var y := 10;
if 10 ≤ x ≤ 15 then
writeLn("x is between 10 and 15").
``````

The above check essentially expands to

``````if (10 ≤ x) and (x ≤ 15) then.
...
``````

## Arithmetic Operators

Supported Operators: `+`, `-`, `*`, `/`, `**`, `div`, `mod`

The above operators are used to carry out mathematical operations on two operands

• `+` evaluates to the sum of two values by adding them.
• `-` evaluates to the difference of two values by subtracting them.
• `*` evaluates to the product of two values by multiplying them.
• `/` evaluates to the fraction of two values by dividing them.
• `**` evaluates to the power of two values.

• `div` also evaluates to the fraction of two values by dividing them. It is provided for Compatibility with Delphi (see below).

• `mod` evaluates to the remainder of two values left over when performing an integer division.
``````var a := 2+2; // 4
var b := 12+3; // 9
var c := 3*9; // 27
var d := 8/2; // 4
var d := 2**10; // 1024

var d := 10.0/4.0; // 2.5
var d := 10.0 div 4.0; // 2.5
var d := 10.0 mod 4.0; // 2
``````

Note that all operators use the type of the input values as result type. For example Dividing two integers will always perform an integer division, producing an integer, potentially losing the remainder. If one of the two operands is a floating point type, the result will be a float, as well.

Also note that Oxygene will apply operator precedence (more on that below for combined expressions, according to mathematical rules (`*` an `/` tage precedence before `+` and `-`, etc).

``````var a :=  5 +  10  * 2;  // 25
var b :=  5 + (10  * 2); // 25
var b := (5 +  10) * 2); // 30
``````

Note on Delphi Compatibility Mode: The `/` and `div` operators will behave differently in Delphi Compatibility Mode. As in Delphi, the operators will not infer the result from the operands. Instead , `/` will always result in a floating point, while `div` will always perform an rounded integer division.

## Logical Operators

Supported Operators: `and`, `or`, `xor`, `not` and `implies`

The above operators can be used to combine boolean expressions. `and`, `or` and `xor` are binary operators, which means the take two parameters; `not` is a unary prefix operator and takes one parameter to it's right.

• `and` returns `true`, if both the expression on the left and the one on the right are true.
• `or` returns `true`, if either one of the expression on the left or the right is true.
• `xor` returns `true`, if only one of the expression on the left or the right is true, but not both.
• `not` returns `true`, if the value it precedes is `false`, otherwise it returns `true`. In other words, it reverses or negates the boolean value.
• `implies` returns `false`, only if the expression on the left is `true`, but the the expression on the right is not.
``````var a := x and y;
var b := x or y;
var c := x xor y;
var d := not x;
var e := x implies y;
``````

By default, Oxygene will apply Boolean Short-Circuit, where starting from the left, the compiler will stop evaluating expressions once the outcome of the expression is determined.

For example, if the left-hand side of an `and` operation is `false`, the result will always be `false`. Likewise, if the left-hand side of an `or` operation is `true`, the result will always be `true`. In both cases, evaluation of the right will not be evaluated at all.

Note that different than in many other, especially C-based languages, the logical `and`, `or` and `xor` operators take precedence over comparisons. For this reason, combining multiple comparisons with logical operators will often require parenthesis:

``````if x > 5 and y < 10 then ... // 🛑 compiler error, because "(5 and y)" would be evaluated first
if (x > 5) and (y < 10) then ... // ✅ works!
``````

## Bitwise Operators

Supported Operators: `and`, `or`, `xor` and `not`

The save four operators can also be used for bitwise operations on numeric (integer) values. When doing so, they apply above boolean logic on each bit of the numeric value's in-memory representation, with 0 and 1 represening `false` or `true`, respectively.

• `and` returns `1` for very bit that is `1` in both the expression on the left and the one on the right.
• `or` returns `1`, for every bit that is `1` either one of the expression on the left or the right.
• `xor` returns `1` for every bit that is `1` in only one of the expression on the left or the right, but not both.
• `not` returns `1`, for every bit that is `0`, and `0` for every bit that is one. In other words, it inverts the bit mask of the value.
``````var a := %0000 1100 and \$0000 1010;  // %0000 1000
var b := %0000 1100 or  \$0000 1010;  // %0000 1110
var c := %0000 1100 and \$0000 1010;  // %1111 0110
var d := not %0000 1100              // %1111 0011
``````

...

## Nesting Expressions with Parenthesis

Parenthesis allow you to visually enclose sub-expressions in order to indicate the order of precedence in which they will be executed within a larger expression. This is especially helpful when using the arithmetic and logical expressions discussed in this topic, but can also help clarify other more complex expressions.

``````var x := 3 + 2 * 5 // evaluates to 3 + 10 = 13, as * has precedence over + by default.
var x := (3 + 2) * 5 // evaluates to 5 * 5 = 25, as the parenthesis cause the addition to be performed first.
``````

## Nullable Types in Expressions

Please refer to the Nullable Types In Expressions topic for some caveats when using expressions that contain potential nil `values`. In particular, a `nil` value anywhere in an operator expression propagates outwards, potentially turning the entire expression `nil`. This can have some unintuitive results when working wit booleans, in particular in combination with the `not` operator, where `not nil` remains `nil`. Also consider Boolean Short-Circuit.