# FunC operators (https://docs-fpm2731fy-ton-core-docs.vercel.app/llms/languages/func/operators/content.md)



<Callout type="note">
  The official smart contract language of TON Blockchain is [Tolk](/llms/tolk/overview/content.md). FunC is now a **legacy** language, with its compiler no longer maintained.

  Learn how to [migrate from FunC to Tolk](/llms/tolk/from-func/tolk-vs-func/content.md). For new smart contract projects, use the [Acton toolchain](/llms/contract-dev/acton/content.md).
</Callout>

This page lists all the operators in FunC in decreasing order of their precedence, with examples of usage.

## Table of operators [#table-of-operators]

<Callout>
  Currently, all the unary and binary operators are integer operators. Logical operators are bitwise integer operators (cf. [absence of boolean type](/llms/languages/func/types/content.md)).
</Callout>

The following table lists operators in order of decreasing precedence, from highest to lowest.

| Brief description       | Operators                                                                                                                                                                                                                                                                         |
| ----------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Parentheses             | [`(` `)`](#parentheses)                                                                                                                                                                                                                                                           |
| Unary bitwise NOT       | [`~`](#bitwise-not%2C)                                                                                                                                                                                                                                                            |
| Multiplicative          | [`*`](#multiplication%2C) [`/`](#division%2C-%2F) [`^/`](#ceiling-division%2C-%5E%2F) [`~/`](#rounding-division%2C-%2F) [`%`](#modulo%2C-%25) [`^%`](#ceiling-modulo%2C-%5E%25) [`~%`](#rounding-modulo%2C-%25) [`/%`](#division-and-modulo%2C-%2F%25) [`&`](#bitwise-and%2C-%26) |
| Unary integer negation  | [`-`](#negation%2C)                                                                                                                                                                                                                                                               |
| Additive                | [`+`](#addition%2C-%2B) [`-`(integer subtraction)](#subtraction%2C) [`\|`](#bitwise-or%2C-%7C) [`^`](#bitwise-xor%2C-%5E)                                                                                                                                                         |
| Shifts                  | [`>>`](#shift-right%2C-%3E%3E) [`<<`](#shift-left%2C-%3C%3C) [`^>>`](#ceiling-shift-right%2C-%5E%3E%3E) [`~>>`](#rounding-shift-right%2C-%3E%3E)                                                                                                                                  |
| Comparison and Equality | [`>`](#greater-than%2C-%3E) [`>=`](#greater-than-or-equal%2C-%3E%3D) [`<`](#less-than%2C-%3C) [`<=`](#less-than-or-equal%2C-%3C%3D) [`<=>`](#comparison%2C-%3C%3D%3E) [`==`](#equality%2C-%3D%3D) [`!=`](#inequality%2C-%3D)                                                      |
| Ternary                 | [`?:`](#ternary%2C-%3F%3A)                                                                                                                                                                                                                                                        |
| Assignment              | [`=`](#assignment%2C-%3D) and all [augmented assignment operators](#augmented-assignment-operators)                                                                                                                                                                               |

All [binary operators](#binary-operators) are left-associative, with the exception of:

* [Assignment operators](#assignment%2C-%3D) (i.e., bottom row in the table), which are right-associative.
* [Division-modulo operator](#division-and-modulo%2C-%2F%25) `/%`, which is neither left associative nor right associative.

Also, the [ternary operator](#ternary%2C-%3F%3A) `?:` is right-associative.

For example:

* `1 - 2 + 3` parses as `(1 - 2) + 3`, producing `2` as result.
* `a = b += c = 10` parses as `(a = (b += (c = 10)))`, producing the final values `c = 10`, `b = 11`, and `a = 11`, under the assumption that `b` had value `1` initially.
* `0 ? a : 1 ? b : c` parses as `0 ? a : (1 ? b : c)`, producing `b` as a result.
* `3 /% 5 /% 7` does *not* compile, neither `(3 /% 5) /% 7` nor `3 /% (5 /% 7)`.

<Callout>
  In expressions, all operators should be separated from their arguments, otherwise the expression is interpreted as an [identifier](/llms/languages/func/literals/content.md).

  For example:

  * `- x` - Negates x.
  * `-x` - Interpreted as a single identifier, not an operation.
  * `x + y` - Adds `x` and `y`.
  * `x+y` - Interpreted as a single identifier, not an operation.
</Callout>

## Precedence [#precedence]

Precedence is used to determine which operator should be considered in a particular situation.
Whenever ambiguity arises, FunC prefers operators with higher precedence over those with lower precedence.

For example, consider this expression:

```func
10 - 6 * 2
```

The expression is ambiguous because it could be parsed in two different ways:

```func
(10 - 6) * 2   ;; Evaluate first 10 - 6
10 - (6 * 2)   ;; Evaluate first 6 * 2
```

However, since the multiplication operator `*` has higher precedence than the subtraction operator `-`,
FunC will prefer to evaluate the multiplication first:

```func
10 - (6 * 2)   ;; Evaluate first 6 * 2
```

<Callout type="tip">
  Neglecting precedence rules can often lead to confusing situations with operators.
  The correct order of operations can be ensured by wrapping every operation in parentheses,
  since parentheses have the highest precedence of all expressions and operators.
</Callout>

## Parentheses [#parentheses]

Parentheses (also called round brackets, `()`) are more punctuation symbols than actual operators,
but their [precedence](#precedence) is higher than the precedence of any other operator.
Use parentheses to override the order of operations:

```func
5 * 5 - 2;    ;; 23
5 * (5 - 2);  ;; 15
```

## Unary operators [#unary-operators]

Unary here means that they are applied only to one operand of the given expression.
All unary operators are prefix operators, i.e., placed before the operand.

### Bitwise NOT, `~` [#bitwise-not-]

The tilde (bitwise NOT) operator `~` inverts or flips each bit in the binary
representation of the expression, changing each `1` to `0`, and vice versa.

```func
int answer = 42;
~ answer;     ;; -43
~ (~ answer); ;; 42
~ (~ 0);      ;; 0
```

The `~` operator also behaves as expected on `-1` and `0`, which are the [emulated values](/llms/languages/func/types/content.md) for `true` and `false`:

```func
~ 0;          ;; -1,  NOT false is true
~ (- 1);      ;; 0,   NOT true is false
```

Hence, `~` can work as [logical NOT](https://en.wikipedia.org/wiki/Negation) when computing boolean conditions:

```func
~ (1 <= 4);    ;; 0,  since 1 <= 4 returns true (-1)
1 > 4;         ;; 0,  logically equivalent to previous
```

### Negation, `-` [#negation--]

The minus sign (negation) operator `-` reverses the sign of the expression.

```func
int five = 5;
- five;         ;; -5
- (- five);     ;; 5
- (- 1);        ;; 1
```

## Binary operators [#binary-operators]

Binary here means that they are applied to two operands of the given expression.
All binary operators are infix operators, i.e., placed in the middle of the two operands.

### Multiplication, `*` [#multiplication-]

The asterisk (multiplication) operator `*` is used for multiplication of two values.
Going beyond the range of the integer type will result in an error with [exit code 4](/llms/tvm/exit-codes/content.md): `Integer overflow`.

```func
int five = 5;
five * 2;         ;; 10
five * five;      ;; 25
```

### Division, `/` [#division-]

The slash (division) operator `/` is used for integer division of two values, which truncates toward zero if the result
is positive and away from zero if the result is negative. This is also called [rounding down](https://en.wikipedia.org/wiki/Rounding#Rounding_down)
or rounding toward negative infinity.

An attempt to divide by zero results in an error with [exit code 4](/llms/tvm/exit-codes/content.md): `Integer overflow`.

```func
(- 1) / 5;        ;; -1, rounding down away from 0
(- 1) / (- 5);    ;; 0, rounding down toward zero
1 / (- 5);        ;; -1, rounding down away from 0
1 / 5;            ;; 0, rounding down toward 0
6 / 5;            ;; 1, rounding down toward 0
(- 6) / 5;        ;; -2, rounding down away from 0
```

### Ceiling division, `^/` [#ceiling-division-]

The caret-slash (ceiling division) operator `^/` is used for integer division of two values, which truncates away from zero if the result
is positive and toward zero if the result is negative. This is also called [rounding up](https://en.wikipedia.org/wiki/Rounding#Rounding_up)
or rounding toward positive infinity.

An attempt to divide by zero results in an error with [exit code 4](/llms/tvm/exit-codes/content.md): `Integer overflow`.

```func
(- 1) ^/ 5;       ;; 0, rounding up toward 0
(- 1) ^/ (- 5);   ;; 1, rounding up away from zero
1 ^/ (- 5);       ;; 0, rounding up toward 0
1 ^/ 5;           ;; 1, rounding up away from 0
6 ^/ 5;           ;; 2, rounding up away from 0
(- 6) ^/ 5;       ;; -1, rounding up toward 0
```

### Rounding division, `~/` [#rounding-division-]

The tilde-slash (rounding division) operator `~/` is used for integer division of two values, which truncates to the nearest integer but using the following
tie-breaking rule for half values: if the fractional part is `0.5`, it is truncated away from zero if the result is positive, and truncated toward zero
if the result is negative. This is also called [rounding half up](https://en.wikipedia.org/wiki/Rounding#Rounding_half_up)
or rounding half toward positive infinity.

An attempt to divide by zero results in an error with [exit code 4](/llms/tvm/exit-codes/content.md): `Integer overflow`.

```func
(- 6) ~/ 5;      ;; -1, rounding -1.2 to nearest integer
(- 6) ~/ (- 5);  ;; 1, rounding 1.2 to nearest integer
8 ~/ (- 5);      ;; -2, rounding -1.6 to nearest integer
8 ~/ 5;          ;; 2, rounding 1.6 to nearest integer
3 ~/ 2;          ;; 2, rounding half value 1.5 away from 0
(- 3) ~/ 2;      ;; -1, rounding half value -1.5 toward 0
```

### Modulo, `%` [#modulo-]

The percent sign (modulo) operator `%` is used for obtaining the modulo of integer division, which is the remainder of dividing the operands with the `/` operator.
Concretely, `a % b` is defined as `a - (b * (a / b))`, where `/` is the [division operator](#division%2C-%2F), `*` is the [multiplication operator](#multiplication%2C),
and `-` is the [subtraction operator](#subtraction%2C).

If `b` in the expression `a % b` is `0`, the result is an error with [exit code 4](/llms/tvm/exit-codes/content.md): `Integer overflow`.

```func
(- 6) % 5;       ;; 4, result of formula: -6 - (5 * (-6 / 5))
(- 6) % (- 5);   ;; -1, result of formula: -6 - (-5 * (-6 / -5))
8 % (- 5);       ;; -2, result of formula: 8 - (-5 * (8 / -5))
8 % 5;           ;; 3, result of formula: 8 - (5 * (8 / 5))
3 % 2;           ;; 1, result of formula: 3 - (2 * (3 / 2))
(- 3) % 2;       ;; 1, result of formula: -3 - (2 * (-3 / 2))
```

The result of `%` always has the same sign as the divisor (i.e., `b` is the divisor in the expression `a % b`). This means that the modulo is not the same as the
remainder from [Euclidean division](https://en.wikipedia.org/wiki/Euclidean_division), because in Euclidean division the remainder is always non-negative,
independently of the sign of the divisor. The modulo `%` and the remainder from Euclidean division coincide when both operands are non-negative.

If you want to compute remainders as in Euclidean division by using the `%` operator, the best way is to use only unsigned integers.
Alternatively, consider using the `abs` function to ensure non-negative values:

```func
abs(-3) % abs(-4)   ;; 3, same as 3 % 4
```

### Ceiling modulo, `^%` [#ceiling-modulo-]

The caret-percent sign (ceiling modulo) operator `^%` is used for obtaining the ceiling modulo of integer ceiling division, which is the remainder of dividing the
operands with the `^/` operator.
Concretely, `a ^% b` is defined as `a - (b * (a ^/ b))`, where `^/` is the [ceiling division operator](#ceiling-division%2C-%5E%2F),
`*` is the [multiplication operator](#multiplication%2C), and `-` is the [subtraction operator](#subtraction%2C).

If `b` in the expression `a ^% b` is `0`, the result is an error with [exit code 4](/llms/tvm/exit-codes/content.md): `Integer overflow`.

```func
(- 6) ^% 5;       ;; -1, result of formula: -6 - (5 * (-6 ^/ 5))
(- 6) ^% (- 5);   ;; 4, result of formula: -6 - (-5 * (-6 ^/ -5))
8 ^% (- 5);       ;; 3, result of formula: 8 - (-5 * (8 ^/ -5))
8 ^% 5;           ;; -2, result of formula: 8 - (5 * (8 ^/ 5))
3 ^% 2;           ;; -1, result of formula: 3 - (2 * (3 ^/ 2))
(- 3) ^% 2;       ;; -1, result of formula: -3 - (2 * (-3 ^/ 2))
```

The result of `^%` always has the opposite sign of the divisor (i.e., `b` is the divisor in the expression `a ^% b`).

### Rounding modulo, `~%` [#rounding-modulo-]

The tilde-percent sign (rounding modulo) operator `~%` is used for obtaining the rounding modulo of integer rounding division, which is the remainder of dividing the
operands with the `~/` operator.
Concretely, `a ~% b` is defined as `a - (b * (a ~/ b))`, where `~/` is the [rounding division operator](#rounding-division%2C-%2F),
`*` is the [multiplication operator](#multiplication%2C),
and `-` is the [subtraction operator](#subtraction%2C).

If `b` in the expression `a ~% b` is `0`, the result is an error with [exit code 4](/llms/tvm/exit-codes/content.md): `Integer overflow`.

```func
(- 6) ~% 5;       ;; -1, result of formula: -6 - (5 * (-6 ~/ 5))
(- 6) ~% (- 5);   ;; -1, result of formula: -6 - (-5 * (-6 ~/ -5))
8 ~% (- 5);       ;; -2, result of formula: 8 - (-5 * (8 ~/ -5))
8 ~% 5;           ;; -2, result of formula: 8 - (5 * (8 ~/ 5))
3 ~% 2;           ;; -1, result of formula: 3 - (2 * (3 ~/ 2))
(- 3) ~% 2;       ;; -1, result of formula: -3 - (2 * (-3 ~/ 2))
```

### Division and modulo, `/%` [#division-and-modulo-]

The slash-percent sign (division and modulo) operator `/%` returns a two element [tensor](/llms/languages/func/types/content.md), where the first element is the result
of applying the [division operator](#division%2C-%2F) `/` on the operands,
and the second element is the result of applying the [modulo operator](#modulo%2C-%25) on the operands.

If `b` in the expression `a /% b` is `0`, the result is an error with [exit code 4](/llms/tvm/exit-codes/content.md): `Integer overflow`.

```func
(- 6) /% 5;       ;; (-2, 4), which is: (-6 / 5, -6 % 5)
(- 6) /% (- 5);   ;; (1, -1), which is: (-6 / -5, -6 % -5)
8 /% (- 5);       ;; (-2, -2), which is: (8 / -5, 8 % -5)
8 /% 5;           ;; (1, 3), which is: (8 / 5, 8 % 5)
3 /% 2;           ;; (1, 1), which is: (3 / 2, 3 % 2)
(- 3) /% 2;       ;; (-2, 1), which is: (-3 / 2, -3 % 2)
```

`/%` is the only binary operator that does not associate to the right or to the left:

```func
10 /% 2 /% 3;     ;; Does NOT compile
(10 /% 2) /% 3;   ;; Does NOT compile
10 /% (2 /% 3);   ;; Does NOT compile
```

The reason for this non-associativity of `/%` is that it returns a 2-element tensor. This means that you must decompose the tensor before using the values.
See more about decomposition notation in the [variable declaration](/llms/languages/func/expressions/content.md) section.

```func
(int x, int y) = 10 /% 2;    ;; x stores 5, y stores 0
(int z, int w) = x /% 3;     ;; z stores 1, w stores 2
```

### Bitwise AND, `&` [#bitwise-and-]

The ampersand (bitwise AND) operator `&` applies a [bitwise AND](https://en.wikipedia.org/wiki/Bitwise_operation#AND),
which performs the logical AND operation on each pair of corresponding bits of the operands.
This is useful when we want to clear selected bits of a number, where each bit represents an individual flag or a boolean state.
This makes it possible to “store” up to 257 boolean values per integer, as all integers in FunC are 257-bit signed.

```func
2 & 1;     ;; 0,  since 2 and 1 has no bits in common
4 & 1;     ;; 0,  since 4 and 1 has no bits in common
3 & 1;     ;; 1,  since 3 and 1 has in common only the lowest degree bit
1 & 1;     ;; 1,  & is idempotent, as expected of logical AND
```

The `&` operator also behaves as expected on `-1` and `0`, which are the [emulated values](/llms/languages/func/types/content.md) for `true` and `false`:

```func
0 & 0;          ;; 0,   false AND false is false
0 & (- 1);      ;; 0,   false AND true is false
(- 1) & 0;      ;; 0,   true AND false is false
(- 1) & (- 1);  ;; -1,  true AND true is true
```

Hence, `&` can work as logical AND when computing boolean conditions:

```func
(1 <= 4) & (2 < 3);   ;; -1,  since (1 <= 4) and (2 < 3) both return -1
```

### Addition, `+` [#addition-]

The plus (addition) operator `+` is used for adding numbers together.
Going beyond the range of the integer type will result in an error with [exit code 4](/llms/tvm/exit-codes/content.md): `Integer overflow`.

```func
2 + 2;      ;; 4
- 1 + 1;    ;; 0
```

### Subtraction, `-` [#subtraction--]

The minus (subtraction) operator `-` is used for subtracting numbers from each other.
Going beyond the range of the integer type will result in an error with [exit code 4](/llms/tvm/exit-codes/content.md): `Integer overflow`.

```func
2 - 2;    ;; 0
- 1 - 1;  ;; -2
```

### Bitwise OR, `|` [#bitwise-or-]

The bar (bitwise OR) operator `|` applies a [bitwise OR](https://en.wikipedia.org/wiki/Bitwise_operation#OR), which performs the
logical OR operation on each pair of corresponding bits of the operands.
This is useful when we want to apply a specific [bitmask](https://en.wikipedia.org/wiki/Mask_\(computing\)).

```func
2 & 1;     ;; 3,
4 & 1;     ;; 5,
3 & 1;     ;; 3,
1 & 1;     ;; 1,  | is idempotent, as expected of logical OR
```

The `|` operator also behaves as expected on `-1` and `0`, which are the [emulated values](/llms/languages/func/types/content.md) for `true` and `false`:

```func
0 | 0;          ;; 0,    false OR false is false
0 | (- 1);      ;; -1,   false OR true is true
(- 1) | 0;      ;; -1,   true OR false is true
(- 1) | (- 1);  ;; -1,   true OR true is true
```

Hence, `|` can work as logical OR when computing boolean conditions:

```func
(1 <= 4) | (3 < 2);   ;; -1,  since (1 <= 4) returns -1
```

### Bitwise XOR, `^` [#bitwise-xor-]

The caret (bitwise XOR) operator `^` applies a [bitwise XOR](https://en.wikipedia.org/wiki/Bitwise_operation#XOR), performing the
[logical exclusive OR](https://en.wikipedia.org/wiki/Exclusive_or) operation on each pair of corresponding bits of the operands.
The result in each position is `1` if exactly one of the bits is `1`, or `0` if both bits are `0` or both bits are `1`.
Thus, it compares two bits, yielding `1` if the bits are different and `0` if they are the same.

It is useful for inverting selected bits of an operand (also called toggling or flipping), as any bit can be toggled by “XORing” it with `1`.

```func
6 ^ 2;     ;; 4,
4 ^ 2;     ;; 6,
3 ^ 1;     ;; 2,
1 ^ 1;     ;; 0,
```

The `^` operator also behaves as expected on `-1` and `0`, which are the [emulated values](/llms/languages/func/types/content.md) for `true` and `false`:

```func
0 ^ 0;          ;; 0,    false XOR false is false
0 ^ (- 1);      ;; -1,   false XOR true is true
(- 1) ^ 0;      ;; -1,   true XOR false is true
(- 1) ^ (- 1);  ;; 0,    true XOR true is false
```

### Shift right, `>>` [#shift-right-]

The double greater than (shift right) operator `>>` returns an integer whose binary representation is the left operand value
shifted by the right operand number of bits to the right.
Excess bits shifted off to the right are discarded, and copies of the leftmost bit are shifted in from the left.
This operation is also called "sign-propagating right shift" or "arithmetic right shift" because the sign of the resulting number
is the same as the sign of the left operand.

`x >> n` is a more efficient way to divide `x` by `2^n`, where the division truncation is done by flooring.
In other words, `x >> n` is equivalent to `floor(x / 2^n)`, where `floor` is the [floor function](https://en.wikipedia.org/wiki/Floor_and_ceiling_functions),
`2^n` is exponentiation of `2` by `n`, and `/` is standard [arithmetical division](https://en.wikipedia.org/wiki/Division_\(mathematics\)).

```func
2 >> 1;       ;; 1,  since floor(2 / 2^1) = 1
(- 2) >> 1;   ;; -1, because >> preserves the sign of the left operand,
              ;; or equivalently floor(-2 / 2^1) = -1

8 >> 2;       ;; 2,  since floor(8 / 2^2) = 2
5 >> 1;       ;; 2,  since floor(5 / 2^1) = 2
(- 14) >> 2;  ;; -4  since floor(-14 / 2^2) = -4
```

### Shift left, `<<` [#shift-left-]

The double less-than (shift left) operator `<<` returns an integer whose binary representation is the left operand value shifted to the left
by the number of bits specified by the right operand.
Excess bits shifted off from the left are discarded, and zero bits are shifted in from the right.

`x << n` is a more efficient way to multiply `x` by `2^n`.
In other words, `x << n` is equivalent to `x * 2^n`, where `2^n` is exponentiation of `2` by `n` and `*` is standard arithmetical multiplication.

Exceeding the range of the integer type will result in an error with [exit code 4](/llms/tvm/exit-codes/content.md): `Integer overflow`.

```func
2 << 1;   ;; 4,  since 2 * 2^1 = 4
1 << 5;   ;; 32, since 1 * 2^5 = 32
2 << 5;   ;; 64, since 2 * 2^5 = 64
```

### Ceiling shift right, `^>>` [#ceiling-shift-right-]

The caret-double greater than (ceiling shift right) operator computes an efficient way to divide the left operand by `2^n`, where `n` is the right operand and
the division truncation is done by ceiling.

In other words, `x ^>> n` is equivalent to `ceil(x / 2^n)`, where `ceil` is the [ceil function](https://en.wikipedia.org/wiki/Floor_and_ceiling_functions),
`2^n` is exponentiation of `2` by `n`, and `/` is standard [arithmetical division](https://en.wikipedia.org/wiki/Division_\(mathematics\)).

```func
2 ^>> 1;       ;; 1,  since ceil(2 / 2^1) = 1
(- 2) ^>> 1;   ;; -1, since ceil(-2 / 2^1) = -1
8 ^>> 2;       ;; 2,  since ceil(8 / 2^2) = 2
5 ^>> 1;       ;; 3,  since ceil(5 / 2^1) = 3
(- 14) ^>> 2;  ;; -3  since ceil(-14 / 2^2) = -3
```

### Rounding shift right, `~>>` [#rounding-shift-right-]

The tilde-double greater than (rounding shift right) operator computes an efficient way to divide the left operand by `2^n`, where `n` is the right operand and
the division truncation is done by [rounding half up](https://en.wikipedia.org/wiki/Rounding#Rounding_half_up).
In other words, `x ~>> n` is equivalent to `floor(x / 2^n + 0.5)`, where `floor` is the [floor function](https://en.wikipedia.org/wiki/Floor_and_ceiling_functions),
`2^n` is exponentiation of `2` by `n`, `/` is standard [arithmetical division](https://en.wikipedia.org/wiki/Division_\(mathematics\)), and `+` is standard arithmetical addition.

```func
15 ~>> 3;       ;; 2,  since floor(15 / 2^3 + 0.5) = 2
12 ~>> 3;       ;; 2,  since floor(12 / 2^3 + 0.5) = 2
11 ~>> 3;       ;; 1,  since floor(11 / 2^3 + 0.5) = 1
(- 14) ~>> 3;   ;; -2, since floor(-14 / 2^3 + 0.5) = -2
(- 12) ~>> 3;   ;; -1  since floor(-12 / 2^3 + 0.5) = -1
```

### Greater than, `>` [#greater-than-]

The greater than operator `>` returns `-1` if the left operand is greater than the right operand and `0` otherwise.

```func
2 > 2;          ;; 0
(- 1) > (- 3);  ;; -1
```

### Greater than or equal, `>=` [#greater-than-or-equal-]

The greater than or equal to operator `>=` returns `-1` if the left operand is greater than or equal to the right operand and `0` otherwise.

```func
2 >= 2;           ;; -1
(- 3) >= (- 1);   ;; 0
```

### Less than, `<` [#less-than-]

The less than operator `<` returns `-1` if the left operand is less than the right operand and `0` otherwise.

```func
2 < 2;           ;; 0
(- 3) < (- 1);   ;; -1
```

### Less than or equal, `<=` [#less-than-or-equal-]

The less than or equal to operator `<=` returns `-1` if the left operand is less than or equal to the right operand and `0` otherwise.

```func
2 <= 2;           ;; -1
(- 1) <= (- 3);   ;; 0
```

### Comparison, `<=>` [#comparison-]

The less than or equal or greater than (comparison) operator `<=>`, returns `-1` if the left operand is less than the right operand,
`0` if the left and right operands are equal, or `1` if the left operand is greater than the right operand.

```func
1 <=> 2;           ;; -1
(- 2) <=> (- 2);   ;; 0
2 <=> (- 1)        ;; 1
```

### Equality, `==` [#equality-]

The equality operator `==` checks whether its two operands are equal, returning `-1` if they are and `0` otherwise.
The `==` can only compare integers.

```func
1 == 2;           ;; 0
(- 2) == (- 2);   ;; -1
```

### Inequality, `!=` [#inequality-]

The inequality operator `!=` checks whether its two operands are different, returning `-1` if they are and `0` otherwise.
The `!=` can only compare integers.

```func
1 != 2;           ;; -1
(- 2) != (- 2);   ;; 0
```

### Ternary, `?:` [#ternary-]

The conditional (ternary) operator `?:` is the only operator that takes three operands: a condition followed by a question mark
(`?`), then an [expression](/llms/languages/func/expressions/content.md) to execute (the "consequent" expression) if the condition evaluates to an integer different from `0`, followed by a colon (`:`),
and finally the expression to execute (the "alternative" expression) if the condition evaluates to `0`.
This operator is frequently used as an alternative to an `if...else` statement.

```
<condition> ? <consequent expression> : <alternative expression>
```

Both the consequent and alternative expressions must have the same type. The condition must have the type integer.

```func
2 ? 3 : 4;      ;; 3, since the condition evaluates to an integer different from 0
0 ? 3 : 4;      ;; 4, since the condition evaluates to 0
1 < 2 ? 3 : 4;  ;; 3, since the condition evaluates to -1
1 != 4 ? begin_cell() : 5;   ;; DOES NOT COMPILE: consequent and alternative do not have the same type
```

### Assignment, `=` [#assignment-]

The assignment operator `=` is used to assign the result of an [expression](/llms/languages/func/expressions/content.md) to a variable. After execution, the `=` operator returns the value assigned to the variable.

```func
a = 5;       ;; Assigns 5 to variable a, and returns 5
b = 5 + a;   ;; Assigns 10 to variable b, and returns 10
```

Since the assignment operator returns the assigned value, it can be used in expressions:

```func
(a = 5) + 10;   ;; Assign 5 to a, and the expression evaluates to 15
(a = 5) + a;    ;; Assigns 5 to a, and the expression evaluates to 10,
                ;; since a = 5 evaluates to 5, and 5 + a is 10.
```

The operator `=` is right associative:

```func
(b = a = 5) + b;   ;; Parses as (b = (a = 5)) + b.
                   ;; So, it does the following:
                   ;; (1) a = 5 assigns 5 to a, and returns 5.
                   ;; (2) b = (a = 5) assigns 5 to b, and returns 5.
                   ;; (3) (b = (a = 5)) + b, evaluates to 10, since b has value 5.
                   ;; From here onwards, a and b have value 5.
```

The assignment operator can also occur in [variable declarations](/llms/languages/func/expressions/content.md), which are also expressions:

```func
int x = 5;        ;; Declares integer variable x with value 5, and returns 5.
a = (int y = 5);  ;; Declares integer variable y with value 5, then assigns 5 to a, and returns 5.
                  ;; From here onwards, a has value 5 and y is also available with value 5.
(int z = 5) + z;  ;; Declares integer variable z with value 5, and the expression evaluates to 10,
                  ;; since after the declaration, z has value 5.
                  ;; From here onwards, z is available with value 5.
```

### Augmented assignment operators [#augmented-assignment-operators]

Augmented (or compound) assignment operators such as `+=` combine an operation with an assignment.
Augmented assignments are semantically equivalent to regular assignments `=` but include an operation:

```func
a += 5;
;; is equivalent to:
a = a + 5;
```

After execution, the augmented operator returns the final value assigned to the variable:

```func
int a = 0; int b = 2;
a += 4;         ;; returns 4 and assigns 4 to a,  equivalent to a = a + 4.
b *= 10;        ;; returns 20 and assigns 20 to b, equivalent to b = b * 10.
(b /= 2) + 1;   ;; returns 11 and assigns 10 to b, equivalent to (b = b / 2) + 1.
```

List of augmented assignment operators:

* `*=`, which uses the [multiplication operator](#multiplication%2C) `*`.
* `/=`, which uses the [division operator](#division%2C-%2F) `/`.
* `^/=`, which uses the [ceiling division operator](#ceiling-division%2C-%5E%2F) `^/`.
* `~/=`, which uses the [rounding division operator](#rounding-division%2C-%2F) `~/`.
* `%=`, which uses the [modulo operator](#modulo%2C-%25) `%`.
* `^%=`, which uses the [ceiling modulo operator](#ceiling-modulo%2C-%5E%25) `^%`.
* `~%=`, which uses the [rounding modulo operator](#rounding-modulo%2C-%25) `~%`.
* `&=`, which uses the [bitwise AND operator](#bitwise-and%2C-%26) `&`.
* `+=`, which uses the [addition operator](#addition%2C-%2B) `+`.
* `-=`, which uses the [subtraction operator](#subtraction%2C) `-`.
* `|=`, which uses the [bitwise OR operator](#bitwise-or%2C-%7C) `|`.
* `^=`, which uses the [bitwise XOR operator](#bitwise-xor%2C-%5E) `^`.
* `>>=`, which uses the [shift right operator](#shift-right%2C-%3E%3E) `>>`.
* `<<=`, which uses the [shift left operator](#shift-left%2C-%3C%3C) `<<`.
* `^>>=`, which uses the [ceiling shift right operator](#ceiling-shift-right%2C-%5E%3E%3E) `^>>`.
* `~>>=`, which uses the [rounding shift right operator](#rounding-shift-right%2C-%3E%3E) `~>>`.
