---
title: Operators
description: "This page lists all the operators in Tact in decreasing order of their precedence, with examples of usage"
prev:
  link: /book/exit-codes
  label: Exit codes
---

Almost every contract operates on data: transforming some values into others. The scope may vary, but operators lie at the core of such modifications.

This page lists all the operators in Tact in decreasing order of their [precedence](#precedence), with examples of usage.

:::note

  Note that there are no implicit type conversions in Tact, so operators can't be used to, say, add values of different types or compare them in terms of equality without explicitly casting them to the same type. That is done with certain functions from the standard library. See [`Int.toString(){:tact}`](/ref/core-strings#inttostring) for an example of such a function.

:::

## Table of operators {#table}

The following table lists operators in order of decreasing [precedence](#precedence), from highest to lowest.

Brief description | Operators
:---------------- | :--------
Parentheses       | [`(){:tact}`][paren]
Unary postfix     | [`!!{:tact}`][nna]
Unary prefix      | [`+{:tact}`][plus] &nbsp; [`-{:tact}`][neg] &nbsp; [`!{:tact}`][inv] &nbsp; [`~{:tact}`][b-not]
Multiplicative    | [`*{:tact}`][mul] &nbsp; [`/{:tact}`][div] &nbsp; [`%{:tact}`][mod]
Additive          | [`+{:tact}`][add] &nbsp; [`-{:tact}`][sub]
Shift             | [`>>{:tact}`][shr] &nbsp; [`<<{:tact}`][shl]
Relational        | [`>{:tact}`][gt] &nbsp; [`>={:tact}`][ge] &nbsp; [`<{:tact}`][lt] &nbsp; [`<={:tact}`][le]
Equality          | [`=={:tact}`][eq] &nbsp; [`!={:tact}`][eq]
Bitwise AND       | [`&{:tact}`][b-and]
Bitwise XOR       | [`^{:tact}`][b-xor]
Bitwise OR        | [`\|{:tact}`][b-or]
Logical AND       | [`&&{:tact}`][l-and]
Logical OR        | [`\|\|{:tact}`][l-or]
Ternary           | [`?:{:tact}`][ternary]
Assignment        | [`={:tact}`][assign] and [all augmented assignment operators](#augmented-assignment)

[paren]: #parentheses

[nna]: #unary-non-null-assert
[plus]: #unary-plus
[neg]: #unary-negate
[inv]: #unary-inverse
[b-not]: #unary-bitwise-not

[mul]: #binary-multiply
[div]: #binary-divide
[mod]: #binary-modulo

[add]: #binary-add
[sub]: #binary-subtract

[shr]: #binary-bitwise-shift-right
[shl]: #binary-bitwise-shift-left

[gt]: #binary-greater
[ge]: #binary-greater-equal
[lt]: #binary-less
[le]: #binary-less-equal

[eq]: #binary-equality

[b-and]: #binary-bitwise-and
[b-xor]: #binary-bitwise-xor
[b-or]: #binary-bitwise-or

[l-and]: #binary-logical-and
[l-or]: #binary-logical-or

[ternary]: #ternary

[assign]: #assignment

## Precedence

All operators on this page are given in order of decreasing precedence, from highest to lowest. Precedence is used to determine which operator should be considered in a particular situation. Whenever ambiguity arises, Tact prefers operators with higher precedence over those with lower precedence.

For example, the minus sign (`-{:tact}`) may be considered either a subtraction operator or a negation operator, which reverses the sign of the expression from plus to minus or vice versa. As the latter has a higher precedence over the former, in cases of ambiguity between the two, Tact will first consider `-{:tact}` as a negation operator. Only if that interpretation does not make sense for the given expression will Tact consider it as a subtraction operator.

Consider the following code:

```tact
5 + -5; // here, the minus sign would be viewed as a negation operator
5 -5;   // while here it would be viewed as a subtraction operator, despite formatting
```

Even though this example may be simple, 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](#parentheses), since parentheses have the highest precedence of all expressions and operators.

## Parentheses, `()` {#parentheses}

Parentheses (also called round brackets, `(){:tact}`) 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:

```tact
5 * 5 - 2;   // 23
5 * (5 - 2); // 15
```

:::note

  The current maximum allowed nesting level of expressions is 83. An attempt to write a deeper expression will result in a compilation error:

  ```tact
  fun elegantWeaponsForCivilizedAge(): Int {
      return
      ((((((((((((((((((((((((((((((((
          ((((((((((((((((((((((((((((((((
              (((((((((((((((((((( // 84 parens, compilation error!
                  42
              ))))))))))))))))))))
          ))))))))))))))))))))))))))))))))
      ))))))))))))))))))))))))))))))));
  }
  ```

:::

## Unary

Unary here means that they are applied only to one operand of the given expression. All unary operators, except for the [non-null assertion](#unary-non-null-assert), have the same [precedence](#precedence).

Unary operators can be one of two types:

* Prefix — placed before the expression.
* Postfix (or suffix) — placed after the expression.

### Non-null assert, `!!` {#unary-non-null-assert}

The unary double-exclamation mark (_non-null assertion_) operator `!!{:tact}` is a postfix operator that enforces non-`null{:tact}` values and allows direct access to the value of the optional variable if it's not `null{:tact}`. Otherwise, it raises a compilation error if the compiler can track it, and if not, throws an exception with [exit code 128](/book/exit-codes#128): `Null reference exception`. It can be applied to any optional variable regardless of its non-`null{:tact}` type.

:::note

  Read more about optional variables and fields here: [Optionals](/book/optionals)

:::

### Plus, `+` {#unary-plus}

The unary plus sign operator `+{:tact}` is a prefix operator that does not alter the value it is applied to. Essentially, it works similar to an [identity function](https://en.wikipedia.org/wiki/Identity_function), but it can only be applied to values of type [`Int{:tact}`][int]:

```tact
let two: Int = +2;
+ two;     // 2
+(+(+2));  // any number of applications gives back the original value, which is 2
- + - two; // 2
+ - + two; // -2
```

### Negate, `-` {#unary-negate}

The unary minus sign (_negation_) operator `-{:tact}` is a prefix operator, which reverses the sign of the expression. It can only be applied to values of type [`Int{:tact}`][int]:

```tact
let five: Int = 5;
five + -five; // here, the minus sign is a negation operator, not a subtraction operator
-(-1);        // double application gives back the original value, which is 1
--1;          // 1
```

### Inverse, `!` {#unary-inverse}

The unary exclamation mark (_inversion_) operator `!{:tact}` is a prefix operator, which inverts the boolean value of the expression—changing `true{:tact}` to `false{:tact}`, and vice versa. It can only be applied to values of type [`Bool{:tact}`][bool]:

```tact
let iLikeTact: Bool = true;
!iLikeTact; // false
!false;     // true
!(!false);  // false
!!false;    // false
```

### Bitwise NOT, `~` {#unary-bitwise-not}

The unary tilde (_bitwise NOT_) operator `~{:tact}` is a prefix operator, which inverts or _flips_ each bit in the binary representation of the expression — changing each $1$ to $0$, and vice versa. It can only be applied to values of type [`Int{:tact}`][int]:

```tact
let answer: Int = 42;
~answer;    // -43
~(~answer); // 42
~(~0);      // 0
~~0;        // 0
```

## Binary

Binary operators are split into several subsections, in order of decreasing [precedence](#precedence). Operators within each subsection have the same [precedence](#precedence) as the subsection itself.

### Multiplication {#binary-multiplication}

Multiply, divide, or obtain a remainder.

#### Multiply, `*` {#binary-multiply}

The binary asterisk (_multiplication_) operator `*{:tact}` is used for multiplication of two values. It can cause [integer overflows](/book/integers#operations).

It can only be applied to values of type [`Int{:tact}`][int]:

```tact
let two: Int = 2;
two * two;         // 4
0 * 1_000_000_000; // 0
-1 * 5;            // -5

pow(2, 255) * pow(2, 255); // build error: integer overflow!
```

#### Divide, `/` {#binary-divide}

The binary slash (_division_) operator `/{:tact}` 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 $-∞$.

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

It can only be applied to values of type [`Int{:tact}`][int]:

```tact
let two: Int = 2;
two / 2; // 1
two / 1; // 2
-1 / 5;  // -1
-1 / -5; // 0
1 / -5;  // -1
1 / 5;   // 0
6 / 5;   // 1, rounding down
-6 / 5;  // -2, rounding down (toward -∞)
```

:::note

  The following relationship between the division and [modulo](#binary-modulo) operators always holds for the `Int{:tact}` type:

  ```tact
  a / b * b + a % b == a; // true for any Int values of `a` and `b`,
                          //   except when `b` is equal to 0 and we divide `a` by 0,
                          //   which is an attempt to divide by zero resulting in an error
  ```

:::

#### Modulo, `%` {#binary-modulo}

The binary percent sign (_modulo_) operator `%{:tact}` is used for obtaining the modulo of integer division, which must not be confused with obtaining the remainder. For two values with the same sign, modulo and remainder operations are equivalent, but when the operands have different signs, the modulo result always has the same sign as the _divisor_ (the value on the right), while the remainder has the same sign as the _dividend_ (the value on the left). This difference can cause the results to differ by one unit of the _divisor_.

It can only be applied to values of type [`Int{:tact}`][int]:

```tact
let two: Int = 2;
two % 2; // 0
two % 1; // 0

1 % 5;   // 1
-1 % 5;  // 4
1 % -5;  // -4
-1 % -5; // -1
```

The simplest way to avoid confusion between obtaining the modulo and obtaining the remainder is to [use only unsigned integers](/book/security-best-practices#misuse-of-signed-integers). Alternatively, consider using the [`abs(){:tact}`](/ref/core-math#abs) function to ensure non-negative values:

```tact
abs(-1) % abs(-5); // 1
```

:::note

  The following relationship between the [division](#binary-divide) and modulo operators always holds for the `Int{:tact}` type:

  ```tact
  a / b * b + a % b == a; // true for any Int values of `a` and `b`,
                          //   except when `b` is equal to 0 and we divide `a` by 0,
                          //   which is an attempt to divide by zero and results in an error
  ```

:::

:::note

  Did you know that in JavaScript, `%{:tact}` works as a _remainder_ operator and not a _modulo_ operator (as it does in Tact)?\
  [Remainder (%) - JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Remainder#description)\
  [Modulo - Wikipedia](https://en.wikipedia.org/wiki/Modulo)

:::

### Addition {#binary-addition}

Add or subtract.

#### Add, `+` {#binary-add}

The binary plus (_addition_) operator `+{:tact}` is used for adding numbers together. Going beyond the maximum value of an [`Int{:tact}`][int] will result in an error with [exit code 4](/book/exit-codes#4): `Integer overflow`.

It can only be applied to values of type [`Int{:tact}`][int]:

```tact
let two: Int = 2;
two + 2; // 4
-1 + 1;  // 0

pow(2, 254) + pow(2, 254);     // 2 * 2^{254}
pow(2, 255) + pow(2, 255);     // build error: integer overflow!
pow(2, 255) - 1 + pow(2, 255); // 2^{256} - 1, maximal value of any integer in Tact!
```

#### Subtract, `-` {#binary-subtract}

The binary minus (_subtraction_) operator `-{:tact}` is used for subtracting numbers from each other. Going beyond the minimum value of an [`Int{:tact}`][int] will result in an error with [exit code 4](/book/exit-codes#4): `Integer overflow`.

It can only be applied to values of type [`Int{:tact}`][int]:

```tact
let two: Int = 2;
two - 2; // 0
-1 - 1;  // -2

pow(2, 254) - pow(2, 254); // 0
pow(2, 255) - pow(2, 255); // 0
pow(2, 256) - pow(2, 256); // build error: integer overflow!
```

### Bitwise shifts {#binary-bitwise-shifts}

Shift bits to the left or to the right.

#### Shift right, `>>` {#binary-bitwise-shift-right}

The binary double greater than (_bitwise shift right_) operator `>>{:tact}` 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_. This is a more efficient way to divide the _left operand_ by $2^n$, where $n$ is equal to the _right operand_.

Can only be applied to values of type [`Int{:tact}`][int]:

```tact
let two: Int = 2;
two >> 1;  // 1
-two >> 1; // -1, because >> performs arithmetic shift right,
           // which preserves the sign of the left operand

4 >> 1; // 2
5 >> 1; // 2, due to flooring of integer values

pow(2, 254) >> 254; // 1
```

:::note

  [Bit shifts - Wikipedia](https://en.wikipedia.org/wiki/Bitwise_operation#Bit_shifts)\
  [Bit manipulation - Wikipedia](https://en.wikipedia.org/wiki/Bit_manipulation)

:::

#### Shift left, `<<` {#binary-bitwise-shift-left}

The binary double less-than (_bitwise shift left_) operator `<<{:tact}` 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. This is a more efficient way to multiply the _left operand_ by $2^n$, where $n$ is equal to the _right operand_. Exceeding the maximum value of an [`Int{:tact}`][int] will result in an error with [exit code 4](/book/exit-codes#4): `Integer overflow`.

Can only be applied to values of type [`Int{:tact}`][int]:

```tact
let two: Int = 2;
two << 1; // 4
1 << 5;   // 1 * 2^5, which is 32
2 << 5;   // 2 * 2^5, which is 64

pow(2, 254) == (1 << 254); // true
pow(2, 254) == 1 << 254; // true, no parentheses needed due to higher precedence of << over ==
pow(2, 255) == 1 << 255; // true, but we're very close to overflow here!
```

:::note

  [Bit shifts - Wikipedia](https://en.wikipedia.org/wiki/Bitwise_operation#Bit_shifts)\
  [Bit manipulation - Wikipedia](https://en.wikipedia.org/wiki/Bit_manipulation)

:::

### Relation {#binary-relation}

Find greater, smaller, or equal values.

#### Greater than, `>` {#binary-greater}

The binary _greater than_ operator `>{:tact}` returns `true{:tact}` if the left operand is greater than the right operand and `false{:tact}` otherwise. Can only be applied to values of type [`Int{:tact}`][int]:

```tact
let two: Int = 2;
two > 2; // false
-1 > -3; // true
```

#### Greater than or equal to, `>=` {#binary-greater-equal}

The binary _greater than or equal to_ operator `>={:tact}` returns `true{:tact}` if the left operand is greater than or equal to the right operand and `false{:tact}` otherwise. Can only be applied to values of type [`Int{:tact}`][int]:

```tact
let two: Int = 2;
two >= 2; // true
-1 >= -3; // true
```

#### Less than, `<` {#binary-less}

The binary _less than_ operator `<{:tact}` returns `true{:tact}` if the left operand is less than the right operand, and `false{:tact}` otherwise. It can only be applied to values of type [`Int{:tact}`][int]:

```tact
let two: Int = 2;
two < 2; // false
-1 < -3; // false
```

#### Less than or equal to, `<=` {#binary-less-equal}

The binary _less than or equal to_ operator `<={:tact}` returns `true{:tact}` if the left operand is less than or equal to the right operand, and `false{:tact}` otherwise. It can only be applied to values of type [`Int{:tact}`][int]:

```tact
let two: Int = 2;
two <= 2; // true
-1 <= -3; // false
```

### Equality and inequality, `==` `!=` {#binary-equality}

The binary equality (_equal_) operator `=={:tact}` checks whether its two operands are _equal_, returning a result of type [`Bool{:tact}`][bool].

The binary inequality (_not equal_) operator `!={:tact}` checks whether its two operands are _not equal_, returning a result of type [`Bool{:tact}`][bool].

Both operators require operands to be of the same type, and neither operator performs implicit type conversions, except for the [`Cell{:tact}`][cell] and [`Slice{:tact}`][slice] types, which are implicitly compared by their hashes.

Both operators can be applied to the following list of types and values:

* [`Int{:tact}`][int]
* [`Bool{:tact}`][bool]
* [`Address{:tact}`][p]
* [`Cell{:tact}`][cell], implicitly compared via [`.hash(){:tact}`](/ref/core-cells#cellhash)
* [`Slice{:tact}`][slice], implicitly compared via [`.hash(){:tact}`](/ref/core-cells#slicehash)
* [`String{:tact}`][p]
* [`map<K, V>{:tact}`](/book/maps), but only if their key and value types are identical
* [Optionals and `null{:tact}` value](/book/optionals)

```tact
// Int:
2 == 3; // false
2 != 3; // true

// Bool:
true == true;  // true
false != true; // true

// Address:
myAddress() == myAddress(); // true
myAddress() != myAddress(); // false

// Cell:
emptyCell() == emptyCell(); // true
emptyCell() != emptyCell(); // false

// Slice:
"A".asSlice() == "A".asSlice(); // true
"A".asSlice() != "A".asSlice(); // false

// String:
"A" == "A"; // true
"A" != "A"; // false

// map<K, V>:
let map1: map<Int, Int> = emptyMap();
let map2: map<Int, Int> = emptyMap();
map1 == map2; // true
map1 != map2; // false

// Optionals and null values themselves
let nullable: Int? = null;
nullable == null; // true
null == null;     // true
nullable != null; // false
null != null;     // false

let anotherNullable: Int? = 5;
nullable == anotherNullable; // false
nullable != anotherNullable; // true
```

:::note

  The binary equality `=={:tact}` and inequality `!={:tact}` operators implicitly compare [maps](/book/maps) by the hashes of their respective [cells][cell] via the [`.hash(){:tact}`](/ref/core-cells#cellhash) function. While this is acceptable in the majority of cases—since most map serializers behave identically to the serializer from TON Blockchain sources—it is still possible to obtain false-negative results if a map is serialized manually or if the serialization logic is modified in certain libraries.

  If you need to guarantee that compared maps are equal and are willing to pay significantly more gas, use the [`map.deepEquals(){:tact}`](/book/maps#deepequals) function.

:::

### Bitwise AND, `&` {#binary-bitwise-and}

The binary ampersand (_bitwise AND_) operator `&{:tact}` applies a [bitwise AND](https://en.wikipedia.org/wiki/Bitwise_operation#AND), which performs the [logical AND](#binary-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 Tact are 257-bit signed.

It can only be applied to values of type [`Int{:tact}`][int]:

```tact
let two: Int = 2;
two & 1; // 0
4 & 1;   // 0
3 & 1;   // 1
1 & 1;   // 1

255 & 0b00001111;        // 15
0b11111111 & 0b00001111; // 15
```

:::note

  [Bitwise AND - Wikipedia](https://en.wikipedia.org/wiki/Bitwise_operation#AND)\
  [Bit manipulation - Wikipedia](https://en.wikipedia.org/wiki/Bit_manipulation)

:::

### Bitwise XOR, `^` {#binary-bitwise-xor}

The binary caret (_bitwise XOR_) operator `^{:tact}` 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$.

It can only be applied to values of type [`Int{:tact}`][int]:

```tact
let two: Int = 2;
two ^ 3; // 1
4 ^ 1;   // 5
3 ^ 1;   // 2
1 ^ 1;   // 0

255 ^ 0b00001111;        // 240
0b11111111 ^ 0b00001111; // 240
```

:::note

  [Bitwise XOR - Wikipedia](https://en.wikipedia.org/wiki/Bitwise_operation#XOR)\
  [Bit manipulation - Wikipedia](https://en.wikipedia.org/wiki/Bit_manipulation)

:::

### Bitwise OR, `|` {#binary-bitwise-or}

The binary bar (_bitwise OR_) operator `|{:tact}` applies a [bitwise OR](https://en.wikipedia.org/wiki/Bitwise_operation#OR), which performs the [logical OR](#binary-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)).

For example, _bitwise OR_ is commonly used in Tact to [combine base modes with optional flags](/book/message-mode#combining-modes-with-flags) by masking specific bits to $1$ in order to construct a target [message `mode`](/book/message-mode).

Can only be applied to values of type [`Int{:tact}`][int]:

```tact
let two: Int = 2;
two | 1; // 3
4 | 1;   // 5
3 | 1;   // 3
1 | 1;   // 1

255 | 0b00001111;        // 255
0b11111111 | 0b00001111; // 255
```

:::note

  [Bitwise OR - Wikipedia](https://en.wikipedia.org/wiki/Bitwise_operation#OR)\
  [Bit manipulation - Wikipedia](https://en.wikipedia.org/wiki/Bit_manipulation)

:::

### Logical AND, `&&` {#binary-logical-and}

The binary logical AND ([logical conjunction](https://en.wikipedia.org/wiki/Logical_conjunction)) operator `&&{:tact}` returns `true{:tact}` if both operands are `true{:tact}` and `false{:tact}` otherwise. It's short-circuited, meaning that it immediately evaluates the entire expression as `false{:tact}` if the left operand is `false{:tact}`, without evaluating the right one.

Can only be applied to values of type [`Bool{:tact}`][bool]:

```tact
let iLikeTact: Bool = true;
iLikeTact && true;  // true, evaluated both operands
iLikeTact && false; // false, evaluated both operands
false && iLikeTact; // false, didn't evaluate iLikeTact
```

### Logical OR, `||` {#binary-logical-or}

The binary logical OR ([logical disjunction](https://en.wikipedia.org/wiki/Logical_disjunction)) operator `||{:tact}` returns `false{:tact}` only if both operands are `false{:tact}`, and `true{:tact}` otherwise. It is short-circuited, meaning that it immediately evaluates the whole expression as `true{:tact}` if the left operand is `true{:tact}`, without evaluating the right one.

This operator can only be applied to values of type [`Bool{:tact}`][bool]:

```tact
let iLikeSnails: Bool = false;
iLikeSnails || true;  // true, evaluated both operands
iLikeSnails || false; // false, evaluated both operands
true || iLikeSnails;  // true, didn't evaluate iLikeSnails
```

## Ternary, `?:` {#ternary}

The conditional (_ternary_) operator is the only Tact operator that takes three operands: a condition followed by a question mark (`?{:tact}`), then an expression to execute if the condition evaluates to `true{:tact}`, followed by a colon (`:{:tact}`), and finally the expression to execute if the condition evaluates to `false{:tact}`. This operator is frequently used as an alternative to an [`if...else{:tact}`](/book/statements#if-else) statement.

The condition must resolve to type [`Bool{:tact}`][bool]:

```tact
// condition
// ↓
true ? "incredibly so" : "absolutely not"; // "incredibly so"
//     ---------------   ----------------
//     ↑                 ↑
//     |                 alternative, when condition is false
//     |
//     consequence, when condition is true

2 + 2 == 4 ? true : false; // true
```

The ternary operator is the only operator with right associativity, besides [assignment-related ones](#assignment). This means that in ambiguous situations, Tact will prefer the longest matching sequence. In short, this makes bracket-less nesting of ternary operators possible, but only for alternative cases (the part that comes after the colon sign `:{:tact}`):

```tact
// don't need additional parentheses for alternative cases
false ? 1 : (false ? 2 : 3); // 3
false ? 1 : false ? 2 : 3;   // also 3
false ? 1 : true ? 2 : 3;    // 2

// need additional parentheses for consequence cases (parts between ? and :)
false ? (false ? 1 : 2) : 3; // 3
false ? false ? 1 : 2 : 3;   // SYNTAX ERROR!
true  ? (false ? 1 : 2) : 3; // 2
```

## Assignment, `=` {#assignment}

The assignment operator `={:tact}` is used to assign a value to a variable or to a field of a [structure](/book/structs-and-messages). The assignment is a statement, and it does not return a value.

```tact
let someVar: Int = 5;    // assignment operator = is used here...
someVar = 4;             // ...and here
someVar = (someVar = 5); // SYNTAX ERROR!
```

### Augmented assignment

Augmented (or compound) assignment operators such as `+={:tact}` combine an operation with an [assignment](#assignment). An augmented assignment is a statement and does not return a value.

Augmented assignments are semantically equivalent to regular assignments but include an operation:

```tact
let value: Int = 5;

// this:
value += 5;
// is equivalent to this:
value = value + 5;
```

List of augmented assignment operators:

* `+={:tact}`, which uses the [addition operator `+{:tact}`](#binary-add). Can only be applied to values of type [`Int{:tact}`][int].
* `-={:tact}`, which uses the [subtraction operator `-{:tact}`](#binary-subtract). Can only be applied to values of type [`Int{:tact}`][int].
* `*={:tact}`, which uses the [multiplication operator `*{:tact}`](#binary-multiply). Can only be applied to values of type [`Int{:tact}`][int].
* `/={:tact}`, which uses the [division operator `/{:tact}`](#binary-divide). Can only be applied to values of type [`Int{:tact}`][int].
* `%={:tact}`, which uses the [modulo operator `%{:tact}`](#binary-modulo). Can only be applied to values of type [`Int{:tact}`][int].
* `&={:tact}`, which uses the [bitwise AND operator `&{:tact}`](#binary-bitwise-and). Can only be applied to values of type [`Int{:tact}`][int].
* `^={:tact}`, which uses the [bitwise XOR operator `^{:tact}`](#binary-bitwise-xor). Can only be applied to values of type [`Int{:tact}`][int].
* `|={:tact}`, which uses the [bitwise OR operator `|{:tact}`](#binary-bitwise-or). Can only be applied to values of type [`Int{:tact}`][int].
* `&&={:tact}`, which uses the [logical AND operator `&&{:tact}`](#binary-logical-and). Can only be applied to values of type [`Bool{:tact}`][p]. Available since Tact 1.6.
* `||={:tact}`, which uses the [logical OR operator `||{:tact}`](#binary-logical-or). Can only be applied to values of type [`Bool{:tact}`][p]. Available since Tact 1.6.
* `<<={:tact}`, which uses the [bitwise shift left operator `<<{:tact}`](#binary-bitwise-shift-left). Can only be applied to values of type [`Int{:tact}`][int]. Available since Tact 1.6.
* `>>={:tact}`, which uses the [bitwise shift right operator `>>{:tact}`](#binary-bitwise-shift-right). Can only be applied to values of type [`Int{:tact}`][int]. Available since Tact 1.6.

```tact
let value: Int = 5;

// +=
value + 5;         // adds 5
value = value + 5; // adds 5 and assigns result back
value += 5;        // also adds 5 and assigns result back

// -=
value - 5;         // subtracts 5
value = value - 5; // subtracts 5 and assigns result back
value -= 5;        // also subtracts 5 and assigns result back

// *=
value * 5;         // multiplies by 5
value = value * 5; // multiplies by 5 and assigns result back
value *= 5;        // also multiplies by 5 and assigns result back

// /=
value / 5;         // divides by 5
value = value / 5; // divides by 5 and assigns result back
value /= 5;        // also divides by 5 and assigns result back

// %=
value % 5;         // gets modulo by 5
value = value % 5; // gets modulo by 5 and assigns result back
value %= 5;        // also gets modulo by 5 and assigns result back

// &=
value & 5;         // bitwise ANDs with 5
value = value & 5; // bitwise ANDs with 5 and assigns result back
value &= 5;        // also bitwise ANDs with 5 and assigns result back

// ^=
value ^ 5;         // bitwise XORs with 5
value = value ^ 5; // bitwise XORs with 5 and assigns result back
value ^= 5;        // also bitwise XORs with 5 and assigns result back

// |=
value | 5;         // bitwise ORs with 5
value = value | 5; // bitwise ORs with 5 and assigns result back
value |= 5;        // also bitwise ORs with 5 and assigns result back

//
// The following augmented assignment operators are available since Tact 1.6
//

// <<=
value << 5;         // bitwise shifts left by 5
value = value << 5; // bitwise shifts left by 5 and assigns result back
value <<= 5;        // also bitwise shifts left by 5 and assigns result back

// >>=
value >> 5;         // bitwise shifts right by 5
value = value >> 5; // bitwise shifts right by 5 and assigns result back
value >>= 5;        // also bitwise shifts right by 5 and assigns result back

let bValue: Bool = true;

// &&=
bValue && false;          // logically ANDs with false
bValue = bValue && false; // logically ANDs with false and assigns result back
bValue &&= false;         // also logically ANDs with false and assigns result back

// ||=
bValue || true;          // logically ORs with true
bValue = bValue || true; // logically ORs with true and assigns result back
bValue ||= true;         // also logically ORs with true and assigns result back
```

[p]: /book/types#primitive-types
[bool]: /book/types#booleans
[int]: /book/integers
[cell]: /book/cells#cells
[slice]: /book/cells#slices
