FunC operators
The official smart contract language of TON Blockchain is Tolk. FunC is now a legacy language, with its compiler no longer maintained.
FunC pages will be moved down in the sidebar in mid-April 2026. Here is the preview of a possible future placement, right between "Blockchain foundations" and "Contribute" sections:


Learn how to migrate from FunC to Tolk.
This page lists all the operators in FunC in decreasing order of their precedence, with examples of usage.
Table of operators
Currently, all the unary and binary operators are integer operators. Logical operators are bitwise integer operators (cf. absence of boolean type).
The following table lists operators in order of decreasing precedence, from highest to lowest.
| Brief description | Operators |
|---|---|
| Parentheses | ( ) |
| Unary bitwise NOT | ~ |
| Multiplicative | * / ^/ ~/ % ^% ~% /% & |
| Unary integer negation | - |
| Additive | + -(integer subtraction) | ^ |
| Shifts | >> << ^>> ~>> |
| Comparison and Equality | > >= < <= <=> == != |
| Ternary | ?: |
| Assignment | = and all augmented assignment operators |
All binary operators are left-associative, with the exception of:
- Assignment operators (i.e., bottom row in the table), which are right-associative.
- Division-modulo operator
/%, which is neither left associative nor right associative.
Also, the ternary operator ?: is right-associative.
For example:
1 - 2 + 3parses as(1 - 2) + 3, producing2as result.a = b += c = 10parses as(a = (b += (c = 10))), producing the final valuesc = 10,b = 11, anda = 11, under the assumption thatbhad value1initially.0 ? a : 1 ? b : cparses as0 ? a : (1 ? b : c), producingbas a result.3 /% 5 /% 7does not compile, neither(3 /% 5) /% 7nor3 /% (5 /% 7).
In expressions, all operators should be separated from their arguments, otherwise the expression is interpreted as an identifier.
For example:
- x- Negates x.-x- Interpreted as a single identifier, not an operation.x + y- Addsxandy.x+y- Interpreted as a single identifier, not an operation.
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:
10 - 6 * 2The expression is ambiguous because it could be parsed in two different ways:
(10 - 6) * 2 ;; Evaluate first 10 - 6
10 - (6 * 2) ;; Evaluate first 6 * 2However, since the multiplication operator * has higher precedence than the subtraction operator -,
FunC will prefer to evaluate the multiplication first:
10 - (6 * 2) ;; Evaluate first 6 * 2Neglecting 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.
Parentheses
Parentheses (also called round brackets, ()) are more punctuation symbols than actual operators,
but their precedence is higher than the precedence of any other operator.
Use parentheses to override the order of operations:
5 * 5 - 2; ;; 23
5 * (5 - 2); ;; 15Unary 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, ~
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.
int answer = 42;
~ answer; ;; -43
~ (~ answer); ;; 42
~ (~ 0); ;; 0The ~ operator also behaves as expected on -1 and 0, which are the emulated values for true and false:
~ 0; ;; -1, NOT false is true
~ (- 1); ;; 0, NOT true is falseHence, ~ can work as logical NOT when computing boolean conditions:
~ (1 <= 4); ;; 0, since 1 <= 4 returns true (-1)
1 > 4; ;; 0, logically equivalent to previousNegation, -
The minus sign (negation) operator - reverses the sign of the expression.
int five = 5;
- five; ;; -5
- (- five); ;; 5
- (- 1); ;; 1Binary 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, *
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: Integer overflow.
int five = 5;
five * 2; ;; 10
five * five; ;; 25Division, /
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
or rounding toward negative infinity.
An attempt to divide by zero results in an error with exit code 4: Integer overflow.
(- 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 0Ceiling 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
or rounding toward positive infinity.
An attempt to divide by zero results in an error with exit code 4: Integer overflow.
(- 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 0Rounding 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
or rounding half toward positive infinity.
An attempt to divide by zero results in an error with exit code 4: Integer overflow.
(- 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 0Modulo, %
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, * is the multiplication operator,
and - is the subtraction operator.
If b in the expression a % b is 0, the result is an error with exit code 4: Integer overflow.
(- 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, 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:
abs(-3) % abs(-4) ;; 3, same as 3 % 4Ceiling 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,
* is the multiplication operator, and - is the subtraction operator.
If b in the expression a ^% b is 0, the result is an error with exit code 4: Integer overflow.
(- 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, ~%
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,
* is the multiplication operator,
and - is the subtraction operator.
If b in the expression a ~% b is 0, the result is an error with exit code 4: Integer overflow.
(- 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, /%
The slash-percent sign (division and modulo) operator /% returns a two element tensor, where the first element is the result
of applying the division operator / on the operands,
and the second element is the result of applying the modulo operator on the operands.
If b in the expression a /% b is 0, the result is an error with exit code 4: Integer overflow.
(- 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:
10 /% 2 /% 3; ;; Does NOT compile
(10 /% 2) /% 3; ;; Does NOT compile
10 /% (2 /% 3); ;; Does NOT compileThe 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 section.
(int x, int y) = 10 /% 2; ;; x stores 5, y stores 0
(int z, int w) = x /% 3; ;; z stores 1, w stores 2Bitwise AND, &
The ampersand (bitwise AND) operator & applies a bitwise 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.
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 ANDThe & operator also behaves as expected on -1 and 0, which are the emulated values for true and false:
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 trueHence, & can work as logical AND when computing boolean conditions:
(1 <= 4) & (2 < 3); ;; -1, since (1 <= 4) and (2 < 3) both return -1Addition, +
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: Integer overflow.
2 + 2; ;; 4
- 1 + 1; ;; 0Subtraction, -
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: Integer overflow.
2 - 2; ;; 0
- 1 - 1; ;; -2Bitwise OR, |
The bar (bitwise OR) operator | applies a bitwise 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.
2 & 1; ;; 3,
4 & 1; ;; 5,
3 & 1; ;; 3,
1 & 1; ;; 1, | is idempotent, as expected of logical ORThe | operator also behaves as expected on -1 and 0, which are the emulated values for true and false:
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 trueHence, | can work as logical OR when computing boolean conditions:
(1 <= 4) | (3 < 2); ;; -1, since (1 <= 4) returns -1Bitwise XOR, ^
The caret (bitwise XOR) operator ^ applies a bitwise XOR, performing the
logical 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.
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 for true and false:
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 falseShift 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,
2^n is exponentiation of 2 by n, and / is standard arithmetical division.
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) = -4Shift 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: Integer overflow.
2 << 1; ;; 4, since 2 * 2^1 = 4
1 << 5; ;; 32, since 1 * 2^5 = 32
2 << 5; ;; 64, since 2 * 2^5 = 64Ceiling 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,
2^n is exponentiation of 2 by n, and / is standard arithmetical division.
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) = -3Rounding 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.
In other words, x ~>> n is equivalent to floor(x / 2^n + 0.5), where floor is the floor function,
2^n is exponentiation of 2 by n, / is standard arithmetical division, and + is standard arithmetical addition.
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) = -1Greater than, >
The greater than operator > returns -1 if the left operand is greater than the right operand and 0 otherwise.
2 > 2; ;; 0
(- 1) > (- 3); ;; -1Greater 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.
2 >= 2; ;; -1
(- 3) >= (- 1); ;; 0Less than, <
The less than operator < returns -1 if the left operand is less than the right operand and 0 otherwise.
2 < 2; ;; 0
(- 3) < (- 1); ;; -1Less 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.
2 <= 2; ;; -1
(- 1) <= (- 3); ;; 0Comparison, <=>
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.
1 <=> 2; ;; -1
(- 2) <=> (- 2); ;; 0
2 <=> (- 1) ;; 1Equality, ==
The equality operator == checks whether its two operands are equal, returning -1 if they are and 0 otherwise.
The == can only compare integers.
1 == 2; ;; 0
(- 2) == (- 2); ;; -1Inequality, !=
The inequality operator != checks whether its two operands are different, returning -1 if they are and 0 otherwise.
The != can only compare integers.
1 != 2; ;; -1
(- 2) != (- 2); ;; 0Ternary, ?:
The conditional (ternary) operator ?: is the only operator that takes three operands: a condition followed by a question mark
(?), then an expression 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.
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 typeAssignment, =
The assignment operator = is used to assign the result of an expression to a variable. After execution, the = operator returns the value assigned to the variable.
a = 5; ;; Assigns 5 to variable a, and returns 5
b = 5 + a; ;; Assigns 10 to variable b, and returns 10Since the assignment operator returns the assigned value, it can be used in expressions:
(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:
(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, which are also expressions:
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 (or compound) assignment operators such as += combine an operation with an assignment.
Augmented assignments are semantically equivalent to regular assignments = but include an operation:
a += 5;
;; is equivalent to:
a = a + 5;After execution, the augmented operator returns the final value assigned to the variable:
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*./=, which uses the division operator/.^/=, which uses the ceiling division operator^/.~/=, which uses the rounding division operator~/.%=, which uses the modulo operator%.^%=, which uses the ceiling modulo operator^%.~%=, which uses the rounding modulo operator~%.&=, which uses the bitwise AND operator&.+=, which uses the addition operator+.-=, which uses the subtraction operator-.|=, which uses the bitwise OR operator|.^=, which uses the bitwise XOR operator^.>>=, which uses the shift right operator>>.<<=, which uses the shift left operator<<.^>>=, which uses the ceiling shift right operator^>>.~>>=, which uses the rounding shift right operator~>>.
Last updated on