×

Dart Operators Precedence and Associativity

Precedence of operators determines the order in which the operators are evaluated if they are grouped together in a sentence. If two operators share an operand then the one with the higher precedence is executed first.

Program

Consider the following code in Dart that uses two Arithmetic Operators viz multiply (*) and add (+), and an assignment operator viz. equals to (=).

void main( )
{
    int a = 5, b = 6, c = 7, res1 = 0, res2 = 0 ;
  
    res1 = a + b * c ;
  
    // result of first expression
    print( res1 ) ;
  
    res2 = a * b + c ;
    
    // result of second expression
    print( res2 ) ;
}

Output:

47
37

Let us understand how the answers to these two results differ. In the first expression res1 = a + b * c with a = 5, b = 6, and c = 7.

Multiplication is performed first because it has higher precedence than the addition operator.

Therefore, the answer evaluated to 47.

res1 = a + b * c = 5 + 6 * 7

                                 = 5 + 42

                              = 47

Similarly in case of second expression,

Multiplication is performed first followed by addition

res2 = a * b + c = 5 * 6 + 7

                                = 30 + 7

                                = 37

Since the assignment operator has the least precedence out of these three, it is used at the last after we have evaluated the expression at the right. And then using assignment operator the value evaluated is assigned to the variable on the left.

Sometimes, the operators with same precedence are used in an expression together. In that case we need a rule that defines the order in which they should be performed and that is given by Associativity of the operators. It determines the direction in which an expression is evaluated. It can be either Left to Right or Right to Left.

Program

Consider the following code in Dart that uses Multiplicative operators  : multiply (*) and divide (/), Additive Operators : add (+) and subtract (-) and assignment operator : equals to (=)

void main( )
{
    int a = 12, b = 6, c = 16, d = 8;
    var res1, res2, res3, res4;
  
    res1 = a - b + c * d;
  
    // result of first expression
    print( res1 ) ;
  
    res2 = a / b * c + d ;
    
    // result of second expression
    print( res2 ) ;
  
    res3 = a * b / c - d ;
  
    // result of third expression
    print( res3 ) ;
  
    res4 = a + b - c / d ;
  
    // result of fourth expression
    print( res4 ) ;
}

Output:

134
40
-3.5
16

PRECEDENCE AND ASSOCIATIVITY TABLE

Let’s have a look at the table that defines the precedence and associativity of each operator in Dart.

LEVELCATEGORYOPERATORASSOCIATIVITY
16Unary Postfixexpr.
expr ?.
expr ++
expr --
expr1
[ expr2 ]
expr( )
 
15Unary Prefix- expr
! expr
++ expr
-- expr
~ expr
await expr
 
14Multiplicative*
/
~
/
%
Left – to - right
13Additive+
-
Left - to - right
12Shift< <
> >
> > > >
Left – to - right
11Bitwise AND&Left - to - right
10Bitwise XOR^Left – to - right
9Bitwise OR Postrix|Left – to - right
8Relation and Test type< 
> 
< =
> =
as
is
is! 
 
7Equality= =
= !
 
6Logical AND&&Left – to - right
5Logical OR| |Left - to - right
4If nullexpr1 ?? expr2Left – to - right
3Conditionalexpr ? expr1 : expr2Right - to - left
2Cascade. .Left – to - right
1Assignment=
* =
/ =
+ =
- =
& =
^ =
< * lt ; =
>> =
?? =
~ / =.
| =
% =
Right - to - left

Overriding Precedence

We are clear by now that the operators are executed in an expression as per their precedence. But what if we want them to be executed exactly in the sequence they are written in an expression?

For example

In an expression that contains multiplication operator (*) and addition operator (+), we know that multiplication will be done first. But in order to perform addition first, we can use round parenthesis with the operator and operands.

Consider the following code in Dart that explains the above point

void main( )
{
    int a = 5, b = 6, c = 7;
    var res1, res2, res3, res4 ;
  
    res1 = a + b * c ;
    
    // printing the result of first expression
    print( res1 ) ;
  
    res2 = a * b + c ; 
  
    // printing the result of second expression
    print( res2 ) ;
  
    res3 = ( a + b ) * c ;
  
    // printing the result of third expression
    print( res3 ) ;
  
    res4 = ( a * b ) + c ;
  
    // printing the result of fourth expression
    print( res4 ) ;
} 

Output:

47
37
77
37

Precedence Class

A particular row in the Dart expression precedence table is represented by an instance of the expression class. This allows programmers to determine when parentheses are required (by comparing precedence values), but ensures that the programmer does not depend on the particular integers used by the analyser to represent table rows, since it may be required to change these integers from time to time to accommodate new language features.

Constructors

  1. Precedence.forTokenType constructor = This constructor is used to construct the precedence of the unary or binary expression containing operators of a particular given ‘type’.

Implementation = Precedence.forTokenType ( TokenType type ) : this._( type.precedence ) ;

Properties

1. HashCode =

Returns the hash code for a numerical value, and it returns the same value for int and doubles when the value provided is the same. 

Implementation =

@override

int get hashCode = > _index.hashCode ;

2. Runtime Type =

Represents the type of runtime an object has. 

Implementation = external Type get runtimeType ;

Operators

1. Operator <

It checks whether the precedence represents a looser binding than other, and accordingly returns true or false.

Implementation = bool operator < ( Precedence other ) = > _index < other._index ;

2. Operator < =

It checks whether the precedence represents a looser, or equal binding than other, and accordingly returns true or false.

Implementation = bool operator < = ( Precedence other ) = > _index < = other._index ;

3. Operator = =

It returns true if and only if this object and the other are the same.

Implementation =

@override

bool operator = = ( Object other ) = >

    other is Precedence && _index = = other._index ;

4. Operator >

It checks whether the precedence represents a tighter binding than other, and accordingly returns true or false.

Implementation = bool operator > ( Precedence other ) = > _index > other._index ;

5. Operator > =

It checks whether the precedence represents a tighter, or equal binding than other, and accordingly returns true or false.

Implementation = bool operator > = ( Precedence other ) = > _index > = other._index ;


Related Topics

Dart Logical Operators

Logical operators are the operators that combine two or more conditions, and accordingly return a Boolean value : true or false. Assume the value of variable A is 25 and B...

2 minutes read.

Dart Arithmetic Operators

Arithmetic Operators comprises of all the operators that are used to perform arithmetic operations such as addition, subtraction, multiplication, division, etc. They are binary operators that work upon two operands. Consider A...

2 minutes read.

Typedef in Dart

In Dart, typedef is used to generate a function type that we can use as a type annotation for declaring variables and return types of the function type. An alias...

4 minutes read.

Dart Comments

Comments are the statements that are used to enhance the readability and understandability of the code. The compiler does not execute these lines. It simply ignores these comments when it scans...

2 minutes read.

Dart Symbols

Symbols data type in Dart A symbol is an object that is the representation of an operator or identifier in Dart. These are compile-time constants.  They are used in APIs that refer...

1 minute read.

Dart Numbers

Dart provides an in-built data type ‘Numbers’ that provides two types of values: intdouble 1. int data type int data type supports integer values, and their size or values range is platform-dependent. Integers...

4 minutes read.

Dart Equality and Relational Operators

Dart provides the functionality of checking the relationship between the values or values within the variables. These operators return the resultant value as Boolean, i.e., either ‘true’ or ‘false’. Some important points...

3 minutes read.

Dart Common Collection Methods

Most of the programming languages have arrays as a way to list items together. However, Dart has a collection of data structures similar to array. These are supported by the...

3 minutes read.

Builder Classes in Dart

Before understanding builder classes, let us understand about Flutter that makes the best use of the builder classes. Flutter is actually not a programming language, it is a software development...

6 minutes read.

Dart If-else statement

In the previous section, we studied about if statements in detail. If – block is executed when the condition evaluates to true, else if the condition evaluates to false, then...

1 minute read.

Dart Switch Case Statement

In the case of if-else statements, we prefer not to use the if-else ladder when there are many test conditions to be evaluated. In such a situation, it is preferable...

4 minutes read.

Unit Testing in Dart

Typing testing ensures that your app keeps working as you add more features or change existing functionality. Unit testing helps to confirm the behavior of a single function, method, or...

4 minutes read.

Dart Features

Dart is a fully-featured, object-oriented modern language with its roots in the programming language ‘Smalltalk’. It has some of its eminent features similar to the languages such as Java, C#...

4 minutes read.

Dart Booleans

Booleans Dart has a data type named ‘bool’ to represent Boolean values : true and false, which are compile-time constants. ‘True’ or ‘False’ cannot be assigned with values 1 or 0. Example, bool...

1 minute read.

Dart Variables

Variables are used to store the value of a particular data type referred to in the whole program by a name or identifier. They refer to a memory location as...

5 minutes read.

Dart Installation Guide

There are various ways of compiling and running an application created in Dart, either by compiling the Dart code to JavaScript using the Dart2js tool or by running on the...

3 minutes read.

Dart Maps

Map is an object-based data structure that associates keys and values that can be of any data type. Every key can occur only once, while the values can be used multiple...

5 minutes read.

Dart Miscellaneous types

Some Other Data types in Dart Apart from the data types studied so far, we have three other data types also which are as follows: NeverDynamicVoid Let us understand each one in detail, Never...

3 minutes read.

Dart Runes and Graphemes

Runes and Graphemes data types in Dart Runes and Graphemes Runes are the special string of Unicode UTF-32 bits that represent the special syntax. Unicode defines a unique numeric value for each...

2 minutes read.

Dart Future and Stream

Before understanding Future and Stream in Dart, we need first to get familiar with two terms : Synchronous and Asynchronous Programming.  In synchronous programming, a single operation is handled at a...

9 minutes read.