On this page28 sections
- Prerequisites
- Connection With Previous Lectures
- Learning Objectives
- 1. What Is an Operator?
- 2. Addition, Subtraction, and Multiplication
- 3. Division with / Always Gives a double
- 4. Integer Division with ~/
- 5. Remainder with %
- 6. Using ~/ and % Together
- 7. Even, Odd, and the Last Digit
- 8. Unary Minus
- 9. int or double? The Result Type
- 10. Which Operator Goes First?
- 11. The Assignment Operator =
- 12. Compound Assignment: += and -=
- 13. *=, /=, ~/=, and %=
- 14. Compound Assignment Keeps the Variable's Type
- 15. += with Strings
- 16. A Real-World Example
- Code Examples
- Common Beginner Mistakes
- Best Practices
- Mini Challenge
- Practice Questions
- Practice Answers
- Quick Revision
- Key Takeaways
- What's Next?
Lecture 17 — Arithmetic & Assignment Operators
| Category | 4 — Operators |
| Lecture | 017 of 140 |
| Estimated video length | 15 min |
| Target | Dart 3.12.2 |
| Level | Beginner |
We have used
+and*since Lecture 001, but we could not split 125 minutes into hours and minutes, or update a balance without writing its name twice. Dart's full set of arithmetic and assignment operators does both.
Contents
Prerequisites · Connection · Objectives · Lesson · Code Examples · Common Mistakes · Best Practices · Mini Challenge · Practice Questions · Answers · Takeaways
Every error message in this lecture is real. Each one was produced by running the code shown on Dart 3.12.2, so you will recognize it when you meet it yourself.
Prerequisites
Students should already understand, from Lectures 001–016:
- declaring variables with a type, with
var, and withfinalandconst - the number types
int,double, andnum, and why adoubleprints.0 - string interpolation with
$nameand${expression} - the null-aware assignment
??=from Lecture 014
Connection With Previous Lectures
Since Lecture 001 we have added, multiplied, and divided numbers. But try a few everyday questions:
void main() {
var minutes = 125;
print(minutes / 60);
}2.0833333333333335Nobody says a film lasts "2.0833 hours". We want 2 hours and 5 minutes, and we have no
way to get the "5". And every time a balance changed, we wrote balance = balance - 250,
typing the name twice. This lecture fills both gaps.
Learning Objectives
By the end of this lecture you will be able to:
- Explain what an operator and an operand are
- Use the arithmetic operators
+,-,*,/,~/, and% - Predict whether a calculation gives an
intor adouble - Split a quantity into whole groups and a leftover with
~/and% - Use unary minus to flip the sign of a value
- Update variables with
=,+=,-=,*=,/=,~/=, and%= - Recognize which compound assignments an
intvariable rejects, and why - Recognize the error messages Dart produces for common operator mistakes
1. What Is an Operator?
An operator is a symbol that does something with values. The values it works on are its
operands. In 7 + 3, the operator is + and the operands are 7 and 3.
Analogy — think of the buttons on a calculator. The numbers are what you type in; the operator buttons decide what happens to them.
void main() {
var result = 7 + 3;
print(result);
}10Most operators sit between two operands. This lecture covers the ones that calculate and the ones that store results.
2. Addition, Subtraction, and Multiplication
+ adds, - subtracts, and * multiplies. They work exactly as on paper:
void main() {
var apples = 12;
var oranges = 5;
print(apples + oranges);
print(apples - oranges);
print(apples * oranges);
}17
7
60Two int operands give an int result, so there is no .0 in sight.
3. Division with / Always Gives a double
The / operator divides — and its answer is always a double, even when the division
comes out even:
void main() {
print(10 / 2);
print(10 / 4);
}5.0
2.5Dart cannot know in advance whether a division will come out even, so / always answers
with the type that can hold a fraction.
4. Integer Division with ~/
Sometimes you only want the whole part. The ~/ operator divides and throws away the
fraction, giving an int:
void main() {
var sweets = 17;
var children = 5;
print(sweets ~/ children);
print(7.5 ~/ 2);
}3
3Each child gets 3 whole sweets. Even 7.5 ~/ 2 (which is 3.75) gives the int 3 —
~/ always returns an int, like truncate() from Lecture 009.
5. Remainder with %
The % operator gives the remainder: what is left over after dividing into whole groups.
void main() {
var sweets = 17;
var children = 5;
print(sweets % children);
print(20 % 5);
}2
017 sweets shared by 5 children: each gets 3, and 2 are left over. A remainder of 0
means the division comes out even. (For negatives, Dart's % never goes below zero: -7 % 3
is 2. You will rarely need this.)
6. Using ~/ and % Together
~/ counts the whole groups and % counts what is left. Together they answer the question
from the start of this lecture:
void main() {
var minutes = 125;
var hours = minutes ~/ 60;
var rest = minutes % 60;
print('$hours h $rest min');
}2 h 5 minThe same pair converts seconds to minutes, items into boxes, or cents into whole coins.
7. Even, Odd, and the Last Digit
A number is even when dividing by 2 leaves nothing over, so % 2 gives 0 for even
numbers and 1 for odd ones. % 10 gives the last digit:
void main() {
var ticket = 4827;
print(ticket % 2);
print(ticket % 10);
}1
7This is how isEven and isOdd from Lecture 009 work inside. Turning ticket % 2 == 0
into a true/false answer needs comparison operators — Lecture 018.
8. Unary Minus
Placed in front of a single value, - flips its sign. Because it has only one operand,
it is called unary minus:
void main() {
var temperature = 8;
var debt = -250;
print(-temperature);
print(-debt);
}-8
250-debt is "minus minus 250", which is 250. Unary minus does not change the variable; it
gives a new value. Remember Lecture 009's warning: -7.abs() means -(7.abs()), so wrap a
negative literal in brackets before calling a method on it.
9. int or double? The Result Type
The operator and the operands together decide the type of the result:
| Expression | Result type | Example |
|---|---|---|
int + - * % int | int | 7 * 3 → 21 |
anything / anything | double | 6 / 3 → 2.0 |
anything ~/ anything | int | 7.5 ~/ 2 → 3 |
int with a double (+ - * %) | double | 5 + 2.0 → 7.0 |
void main() {
print(5 + 2.0);
print(6 / 3);
print(7.5 % 2);
}7.0
2.0
1.5One double operand is enough to make the whole result a double. This matters as soon as
you store the result in a typed variable:
void main() {
int half = 10 / 2;
print(half);
}Error: A value of type 'double' can't be assigned to a variable of type 'int'.
int half = 10 / 2;
^Use ~/ when you want an int, or declare the variable as double.
10. Which Operator Goes First?
As in school maths, *, /, ~/, and % are worked out before + and -. Brackets
go first of all:
void main() {
print(2 + 3 * 4);
print((2 + 3) * 4);
}14
20When in doubt, add brackets — they cost nothing and make your intent clear. We will study the full order of all operators in Lecture 021 — Operator Precedence & Custom Operators.
11. The Assignment Operator =
= is an operator too. It works out the right-hand side first, then stores the result
in the variable on the left:
void main() {
var balance = 1000;
balance = balance - 250;
print(balance);
}750Read = as "becomes", not "equals": balance becomes balance minus 250. Checking whether
two values are equal uses a different operator, ==, in Lecture 018.
12. Compound Assignment: += and -=
"Take the variable, change it, store it back" is so common that Dart has a shortcut.
balance -= 250 means exactly balance = balance - 250:
void main() {
var balance = 1000;
balance -= 250;
print(balance);
balance += 100;
print(balance);
}750
850These are compound assignment operators: an arithmetic operator joined to =. The name
is written once, so there is less to type and less to get wrong.
13. *=, /=, ~/=, and %=
Every arithmetic operator has a compound version:
void main() {
var price = 200.0;
price *= 3;
print(price);
price /= 4;
print(price);
var items = 47;
items ~/= 10;
print(items);
var seconds = 135;
seconds %= 60;
print(seconds);
}600.0
150.0
4
15items ~/= 10 keeps the number of whole tens; seconds %= 60 keeps only the leftover
seconds. You already know one more member of this family: ??= from Lecture 014, which
assigns only when the variable is null.
14. Compound Assignment Keeps the Variable's Type
A compound assignment still stores into the same variable, so the result must fit its type.
An int variable cannot take the double that /= produces:
void main() {
int total = 10;
total /= 4;
print(total);
}Error: A value of type 'double' can't be assigned to a variable of type 'int'.
total /= 4;
^The same happens with total += 2.5. Use ~/= to stay whole, or make the variable a
double from the start.
15. += with Strings
+ joins strings (Lecture 007), so += works on a String variable too — it adds text to
the end:
void main() {
var name = 'Sara';
name += ' Ahmed';
print(name);
}Sara AhmedThe other compound operators have no meaning for text. For building messages, interpolation is still the clearer choice.
16. A Real-World Example
void main() {
const pencilsPerBox = 12;
const boxPrice = 150.0;
var pencils = 100;
var boxes = pencils ~/ pencilsPerBox;
var loose = pencils % pencilsPerBox;
var bill = boxes * boxPrice;
bill += 25;
bill -= bill * 0.1;
print('Full boxes: $boxes');
print('Loose pencils: $loose');
print('Bill: ${bill.toStringAsFixed(2)}');
}Full boxes: 8
Loose pencils: 4
Bill: 1102.50~/ and % split the pencils into full boxes and leftovers. Because boxPrice is a
double, bill is a double, so -= with a 10% discount is allowed. The bill is 1200,
plus 25 delivery, minus 10%.
Code Examples
Example 1 — The Basic Four
void main() {
var a = 20;
var b = 8;
print(a + b);
print(a - b);
print(a * b);
print(a / b);
}28
12
160
2.5Example 2 — / Versus ~/
void main() {
print(9 / 3);
print(9 ~/ 3);
print(10 / 3);
print(10 ~/ 3);
}3.0
3
3.3333333333333335
3Example 3 — Whole Groups and Leftovers
void main() {
var seconds = 250;
var minutes = seconds ~/ 60;
var left = seconds % 60;
print('$minutes min $left sec');
}4 min 10 secExample 4 — Even or Odd
void main() {
print(14 % 2);
print(21 % 2);
print(0 % 2);
}0
1
0Example 5 — Unary Minus
void main() {
var profit = 300;
var loss = -profit;
print(loss);
print(-loss);
}-300
300Example 6 — All Six Compound Operators
void main() {
var value = 50.0;
value += 10;
value -= 5;
value *= 2;
value /= 4;
print(value);
var count = 50;
count ~/= 3;
count %= 7;
print(count);
}27.5
2How it works
valuegoes50.0→60.0→55.0→110.0→27.5.valueis adouble, so/=is allowed.countis anint:50 ~/ 3is16, and16 % 7is2.
Example 7 — Student Marks
void main() {
var student = 'Ali';
var total = 0;
total += 78;
total += 91;
total += 84;
var average = total / 3;
print('Student: $student');
print('Total: $total');
print('Average: ${average.toStringAsFixed(1)}');
print('Whole average: ${total ~/ 3}');
}Student: Ali
Total: 253
Average: 84.3
Whole average: 84How it works
totalstarts at0and collects each mark with+=.total / 3gives thedouble84.33333333333333, formatted to one decimal.total ~/ 3gives the whole-number average,84, as anint.
Example 8 — Shopping Total
void main() {
var total = 0.0;
total += 350 * 2;
total += 120.5;
total *= 0.85;
print('Total after 15% off: ${total.toStringAsFixed(2)}');
}Total after 15% off: 697.42How it works
totalstarts as0.0, so it is adoubleand can take any price.- Two items at
350and one at120.5make820.5. *= 0.85keeps 85% of the total — a 15% discount:697.425, shown as697.42.
Example 9 — Bank Balance
void main() {
var owner = 'Sara';
var balance = 5000.0;
balance -= 1200;
balance += 750;
balance *= 1.02;
print('Owner: $owner');
print('Balance: ${balance.toStringAsFixed(2)}');
}Owner: Sara
Balance: 4641.00How it works
- A withdrawal of
1200and a deposit of750leave4550.0. *= 1.02adds 2% interest:4550 × 1.02is4641.balancemust be adoublefor*= 1.02to compile.
Example 10 — Game Score
void main() {
var player = 'Zayan';
var score = 0;
score += 40;
score += 35;
score *= 2;
score -= 15;
var stars = score ~/ 50;
var toNextStar = 50 - score % 50;
print('Player: $player');
print('Score: $score');
print('Stars: $stars');
print('Points to next star: $toNextStar');
}Player: Zayan
Score: 135
Stars: 2
Points to next star: 15How it works
scoregoes40→75→150→135.- Every
50points earns a star:135 ~/ 50is2. 135 % 50is35points towards the next star, so15more are needed.
Common Beginner Mistakes
1. Storing a / result in an int
void main() {
// int half = 10 / 2; // ✗
}Error: A value of type 'double' can't be assigned to a variable of type 'int'./ always gives a double. Use ~/ for a whole answer.
2. Using /= or += 2.5 on an int variable
void main() {
var total = 10;
// total += 2.5; // ✗
}Error: A value of type 'double' can't be assigned to a variable of type 'int'.var total = 10 made total an int. Write var total = 10.0; if it will hold decimals.
3. Writing =+ instead of +=
void main() {
var count = 5;
// count =+ 2; // ✗
}Error: '+' is not a prefix operator.
Try removing '+'.The arithmetic symbol comes first: +=, -=, *=.
4. Dividing by zero with ~/ or %
void main() {
print(10 / 0);
print(10 ~/ 0);
}Infinity
Unhandled exception:
IntegerDivisionByZeroException/ by zero gives the special double value Infinity, but ~/ and % by zero stop the
program while it is running. (Dart also prints the file locations, left out here.) We will
learn to handle such errors in Category 14 — Error & Exception Handling.
5. Compound-assigning a final variable
void main() {
final total = 10;
// total += 5; // ✗
}Error: Can't assign to the final variable 'total'.+= is still an assignment, and a final variable cannot be assigned again. Use var.
6. Compound-assigning a variable with no value
void main() {
int score;
// score += 5; // ✗
}Error: Non-nullable variable 'score' must be assigned before it can be used.score += 5 must read score first. Start a running total at 0.
7. Forgetting that * and / go before + and -
void main() {
var average = 80 + 90 / 2;
print(average);
}125.0No error — just a wrong answer. Only 90 was halved. Write (80 + 90) / 2 to get 85.0.
Best Practices
- Use
/when you need a fraction and~/when you need whole groups. - Pair
~/with%to split a quantity into groups and a leftover. - Prefer compound operators (
total += price) over repeating the variable name. - Start a running total at
0— or0.0if decimals may be added. - Make a variable a
doublefrom the start if/=or decimal values will reach it. - Add brackets whenever the order of a calculation is not obvious.
- Never
~/or%by a value that could be zero.
Mini Challenge
Sara has 1000 rupees. A notebook costs 135. Work out how many notebooks she can buy, how
much she spends, and her change.
Your program should print exactly:
Notebooks: 7
Spent: 945
Change: 55Try it yourself before opening the solution.
Show solution
void main() {
var money = 1000;
var price = 135;
var notebooks = money ~/ price;
var spent = notebooks * price;
var change = money % price;
print('Notebooks: $notebooks');
print('Spent: $spent');
print('Change: $change');
}Notebooks: 7
Spent: 945
Change: 55How it works
1000 ~/ 135counts the whole notebooks she can afford:7.7 * 135is what she spends:945.1000 % 135is the leftover money:55— the same as1000 - 945.
Practice Questions
Work through these in order — they run from beginner to application to challenge. Every question gives you exact values, so you can compare your output with the answers.
Beginner
- Print the results of
15 + 4,15 - 4,15 * 4, and15 / 4, each on its own line. - Print the results of
23 ~/ 4and23 % 4, each on its own line. - Store
temperature = 12and print it with its sign flipped, using unary minus.
Application
-
Store
number = 37. Print its remainder when divided by2, then its last digit. -
Store
score = 10. Using only compound operators, add5, multiply by3, then subtract9. Print the final score. -
Store
seconds = 3725and print it as1 h 2 min 5 sec. -
This program does not compile. Fix it by changing one operator, so that it prints
81:void main() { var total = 245; int average = total / 3; print(average); } -
Ali's balance is
5000. Using compound operators, withdraw1200, then deposit750, and printBalance: 4550.
Challenge
- A farm packs
100eggs into trays of12. Print the number of full trays, the eggs left over, and how many more eggs are needed to fill one more tray:Full trays: 8,Left over: 4,Needed: 8. - Ali, Sara, and Zayan share a bill of
1000in whole rupees. Each pays the same whole amount, and Ali also pays whatever is left over. PrintEach pays: 333andAli pays: 334.
Practice Answers
Question 1 — Solution
void main() {
print(15 + 4);
print(15 - 4);
print(15 * 4);
print(15 / 4);
}19
11
60
3.75Question 2 — Solution
void main() {
print(23 ~/ 4);
print(23 % 4);
}5
34 fits into 23 five whole times (20), leaving 3.
Question 3 — Solution
void main() {
var temperature = 12;
print(-temperature);
}-12Question 4 — Solution
void main() {
var number = 37;
print(number % 2);
print(number % 10);
}1
7A remainder of 1 when dividing by 2 means the number is odd.
Question 5 — Solution
void main() {
var score = 10;
score += 5;
score *= 3;
score -= 9;
print(score);
}3610 → 15 → 45 → 36.
Question 6 — Solution
void main() {
var seconds = 3725;
var hours = seconds ~/ 3600;
var minutes = seconds % 3600 ~/ 60;
var rest = seconds % 60;
print('$hours h $minutes min $rest sec');
}1 h 2 min 5 secseconds % 3600 is the 125 seconds left after the full hour; ~/ 60 turns them into 2
minutes. % and ~/ have the same priority, so they are worked out left to right.
Question 7 — Solution
Change / to ~/:
void main() {
var total = 245;
int average = total ~/ 3;
print(average);
}81/ would give 81.66666666666667, a double. ~/ gives the whole part as an int.
Question 8 — Solution
void main() {
var balance = 5000;
balance -= 1200;
balance += 750;
print('Balance: $balance');
}Balance: 4550Question 9 — Solution
void main() {
var eggs = 100;
var perTray = 12;
var trays = eggs ~/ perTray;
var left = eggs % perTray;
var needed = perTray - left;
print('Full trays: $trays');
print('Left over: $left');
print('Needed: $needed');
}Full trays: 8
Left over: 4
Needed: 8The partly filled tray already holds 4 eggs, so it needs 12 - 4 more.
Question 10 — Solution
void main() {
var bill = 1000;
var people = 3;
var share = bill ~/ people;
var aliPays = share;
aliPays += bill % people;
print('Each pays: $share');
print('Ali pays: $aliPays');
}Each pays: 333
Ali pays: 3341000 ~/ 3 is 333, and 1000 % 3 is the 1 rupee nobody has paid yet. Ali adds it with
+=: 333 + 333 + 334 is exactly 1000.
Quick Revision
- In
8 * 5, which part is the operator and which are the operands? - Which type does
/always return? - What do
17 ~/ 5and17 % 5give? - How can
%tell you whether a number is even? - What does unary minus do to
-250? - What type is
5 + 2.0, and why? - What does
price *= 3mean, written without the shortcut? - Why does
total /= 4fail whentotalis anint?
Key Takeaways
- An operator works on operands: in
7 + 3,+is the operator. +,-, and*behave as on paper;/divides and always returns adouble.~/divides and keeps only the whole part, as anint;%gives the remainder.- Together,
~/and%split a quantity into whole groups and a leftover. - Unary minus (
-x) flips a value's sign without changing the variable. - Two
ints give anint(except with/); onedoubleoperand makes the result adouble. =works out the right side first, then stores it; compound operators (+=,-=,*=,/=,~/=,%=) combine a calculation with that assignment.- The result of a compound assignment must still fit the variable's type, so
/=is not allowed on anint.
What's Next?
Lecture 18 — Comparison & Equality. We can now calculate answers, but we cannot yet ask
questions about them: is the balance more than the price? Is ticket % 2 equal to 0?
Next we will meet ==, !=, <, >, <=, and >=, which compare two values and answer
with a bool.